"""
Vistas utilizadas
"""
from pyramid.response import Response
from pyramid.renderers import render
import json
import re
import cgi
from sqlalchemy import and_
from sqlalchemy import or_
from pyramid.httpexceptions import HTTPFound, HTTPNotFound
from pyramid.security import authenticated_userid
from alpha.modelos import DBSession
from alpha.modelos.models import DBSession2
from alpha.modelos.models import Usuario
from alpha.modelos.models import Rol
from alpha.modelos.models import Proyecto
from alpha.modelos.models import Fase
from alpha.modelos.models import Permiso
from alpha.modelos.models import Item
from alpha.modelos.models import RelacionSucesor
from alpha.modelos.models import RelacionHijo
from alpha.modelos.models import AsociacionRolPermiso
from alpha.modelos.models import AsociacionUsuarioRol
from alpha.modelos.models import AsociacionFaseTipoItem
from alpha.modelos.models import AsociacionRolProyecto
from alpha.modelos.models import AsociacionRolFase
from alpha.modelos.models import AsociacionRolTipoItem
from alpha.modelos.models import AsociacionItemArchivo
from alpha.modelos.models import TipoItem
from alpha.modelos.models import Atributo
from alpha.modelos.models import Historial
from alpha.modelos.models import Archivo
from alpha.modelos.models import LineaBase
from alpha.modelos.models import eliminar_duplicados
from alpha.modelos.models import compara
from alpha.modelos.models import comparaFase
from alpha.modelos.models import comparaId
from pyramid.security import authenticated_userid, remember, forget
import transaction


def perfil(request): 
	logged_in= authenticated_userid(request)
	return dict( logged_in = logged_in, )

def miembros(request): 
	logged_in= authenticated_userid(request)
	return dict( logged_in = logged_in, )

def configuracion(request): 
	logged_in= authenticated_userid(request)
	return dict( logged_in = logged_in, )
	
def redirect(request):
	"""Redirije la raiz a la vista main"""
	return HTTPFound(location= request.route_url('main'))


def main(request):
	"""Vista main, los usuarios autenticados pueden ver el contenido
	:var logged_in: contiene el nombre del usuario loggeado actualmente
	:return: retorna un diccionario con el nombre del usuario loggeado"""   
	logged_in= authenticated_userid(request)
	return dict( logged_in = logged_in, )


def usuarios(request):
	"""Vista usuarios, seccion donde se administra las operaciones referentes a los usuarios"""     
	logged_in= authenticated_userid(request)
	return dict( logged_in = logged_in, )


def roles(request):
	"""Vista roles, seccion donde se administra las operaciones referentes a los roles"""   
	logged_in= authenticated_userid(request)
	return dict( logged_in = logged_in, )


def proyectos(request):
	"""Vista proyectos, seccion donde se administra las operaciones referentes a los proyectos"""
	logged_in= authenticated_userid(request)
	return dict( logged_in = logged_in, )


def desarrollo(request):
	"""Vista desarrollo, seccion donde se realizan operaciones referentes al desarrollo"""
	logged_in= authenticated_userid(request)
	return dict( logged_in = logged_in, )
	
def gestionConf(request):
	"""Vista gestionConf, seccion donde se realizan operaciones referentes a la Gestion de Configuracion"""
	logged_in= authenticated_userid(request)
	return dict( logged_in = logged_in, )


def asignarUsuarios_desdeABMRol(request):
	"""Funcion que se encarga de asignar o asociar usuarios con un rol especifico
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session = DBSession()
	id_rol= int(request.params['id_rol'])
	lista_usuarios= request.params['lista_usuarios']
	lista_usuarios= lista_usuarios[1:-1].split(',')
	rol= session.query(Rol).filter_by( id= id_rol ).first()
	listaDeRelacionados=  session.query(AsociacionUsuarioRol).filter_by(right_id= id_rol).all()
	lista_sistema= []
	lista_vista= []
	for nombreUsuarioVista in lista_usuarios:
		usuarioAux= session.query(Usuario).filter_by(nombreUsuario= nombreUsuarioVista[1:-1]).first() 
		lista_vista.append(usuarioAux)
	for asociacion in listaDeRelacionados:
		usuario= session.query(Usuario).filter_by(id= asociacion.left_id).first() 
		lista_sistema.append(usuario)
	for usuario in lista_vista:
		if not(usuario in lista_sistema) and usuario != None :
			aso= AsociacionUsuarioRol() 
			aso.rol= rol
			aso.left_id= usuario.id
			usuario.asociacionRol.append(aso)
			session.add(usuario)
	for usuario in lista_sistema:
		if not(usuario in lista_vista):
			for aso in usuario.asociacionRol:
				if aso.right_id == id_rol:
					session.delete(aso)
	output= json.dumps({'success': True})
	return Response(output)


def asignarLider_desdeABMProyecto(request):
	"""Funcion que se encarga de asignar el rol de lider a un proyecto
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session = DBSession()
	id_proyecto= int(request.params['id_proy'])
	lista_usuarios= request.params['lista_usuarios']
	lista_usuarios= lista_usuarios[1:-1].split(',')
	username= lista_usuarios[0]
	usuario_vista= session.query(Usuario).filter_by( nombreUsuario= username[1:-1] ).first()
	proyecto=  session.query(Proyecto).filter_by( id= id_proyecto ).first()
	usuario_sistema= session.query(Usuario).filter_by( id= proyecto.lider_id ).first()
	if usuario_vista == None and usuario_sistema == None:
		output= json.dumps({'success': False, 'mensaje': 'No existe lider asignado al proyecto'})
	elif usuario_sistema != None and usuario_vista == None:
		usuario_sistema.liderProyecto.remove(proyecto)
		proyecto.lider_id= None
		session.add(usuario_sistema)
		session.add(proyecto)
		output= json.dumps({'success': True, 'mensaje':'Lider desasignado correctamente' })
	elif usuario_sistema == None and usuario_vista != None:
		usuario_vista.liderProyecto.append(proyecto)
		session.add(usuario_vista)
		output= json.dumps({'success': True, 'mensaje':'Lider asignado correctamente'})
	else :
		if usuario_vista != usuario_sistema:
			usuario_sistema.liderProyecto.remove(proyecto)
			usuario_vista.liderProyecto.append(proyecto)
			session.add(usuario_sistema)
			session.add(usuario_vista)
			output= json.dumps({'success': True})
		else:
			output= json.dumps({'success': True})
	return Response(output)


def asignarRoles_desdeABMUsuarios(request):
	"""Funcion que se encarga de asignar el rol a un usuario
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session = DBSession()
	id_usuario= int(request.params['id_usuario'])
	lista_roles= request.params['lista_roles']
	lista_roles= lista_roles[1:-1].split(',')
	"""note: obtiene el usuario a modificar"""
	usuario= session.query(Usuario).filter_by(id= id_usuario).first()
	lista_vista= []
	lista_usuario= []
	"""note: roles de la vista que se muestra en la interfaz"""
	for nombreRolVista in lista_roles: 
		rol= session.query(Rol).filter_by(nombre= nombreRolVista[1:-1]).first()
		lista_vista.append(rol)
	"""note: roles que tiene actualmente el usuario"""
	for aux in usuario.asociacionRol:
		lista_usuario.append(aux.rol)
	"""note: si el rol de la vista no esta en los del usuarios se crea la relacion y se anhade"""
	for posible in lista_vista:
		if not (posible in lista_usuario) and posible != None:
			aso= AsociacionUsuarioRol()
			aso.rol= posible
			aso.left_id= usuario.id
			usuario.asociacionRol.append(aso)
	"""note:si el rol que esta en el usuario no esta en la vista, se elimina su relacion con el usuario"""
	for posible in lista_usuario:
		if not(posible in lista_vista):
			for aso in usuario.asociacionRol:
				if aso.rol == posible:
					session.delete(aso)
	session.add(usuario)
	output= json.dumps({'success': True})
	return Response(output)


def asignarPermisos_desdeABMRol(request):
	"""Funcion que se encarga de asignar permisos a un rol
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session = DBSession()
	id_rol= int(request.params['id_rol'])
	lista_permisos= request.params['lista_permisos']
	lista_permisos= lista_permisos[1:-1].split(',')
	"""note: obtiene el rol a modificar"""
	rol= session.query(Rol).filter_by(id= id_rol).first()
	lista_vista= []
	lista_rol= []
	"""note: roles de la vista que se muestra en la interfaz"""
	for nombrePermisoVista in lista_permisos: 
		permiso= session.query(Permiso).filter_by(nombre= nombrePermisoVista[1:-1]).first()
		lista_vista.append(permiso)
	"""note: roles que tiene actualmente el usuario"""
	for aux in rol.asociacionPermiso: 
		lista_rol.append(aux.permiso)
	"""note: si el rol de la vista no esta en los del usuarios se crea la relacion y se anhade"""
	for posible in lista_vista: 
		if not (posible in lista_rol) and posible != None:
			aso= AsociacionRolPermiso()
			aso.permiso= posible
			aso.left_id= rol.id
			rol.asociacionPermiso.append(aso)
	"""note: si el rol que esta en el usuario no esta en la vista, se elimina su relacion con el usuario"""
	for posible in lista_rol:
		if not(posible in lista_vista):
			for aso in rol.asociacionPermiso:
				if aso.permiso == posible:
					session.delete(aso)
	session.add(rol)
	output= json.dumps({'success': True})
	return Response(output)


def asignarProyectos_desdeABMRol(request):
	"""
	Funcion que se encarga de asignar a un rol una o varios proyectos
	:return: retorna al extj un mensaje de si la operacion fue un exito o no
	"""
	session = DBSession()
	id_rol= int(request.params['id_rol'])
	lista_proyectos= request.params['lista_proyectos']
	lista_proyectos= lista_proyectos[1:-1].split(',')
	id_proyectos= []
	if lista_proyectos[0] != '':
		for numero in lista_proyectos:
			id_proyectos.append(int(numero))
	"""
	note: obtiene el rol a modificar
	"""
	rol= session.query(Rol).filter_by(id= id_rol).first()
	lista_vista= []
	lista_project= []
	"""
	note: proyectos que estan al lado derecho del DRAG
	"""
	for id_proyecto in id_proyectos: 
		proyecto= session.query(Proyecto).filter_by(id= id_proyecto).first()
		lista_vista.append(proyecto)
	"""
	note: proyectos que tiene actualmente el rol
	"""
	for aux in rol.asociacionProyecto: 
		lista_project.append(aux.proyecto)
	"""
	note: si el proyecto de la vista (lado derecho del DRAG) no esta asociado con el rol se crea la relacion y se anhade
	"""
	for posible in lista_vista:
		if not (posible in lista_project) and posible != None:
			aso= AsociacionRolProyecto()
			aso.proyecto= posible
			aso.left_id= rol.id
			rol.asociacionProyecto.append(aso)
			if rol.getTipo() == 'LiderProyecto':
				"""note: se anhaden las fases del proyecto que fue asociado"""
				for fase_agregar in posible.fases:
					aso= AsociacionRolFase()
					aso.fase= fase_agregar
					aso.left_id= rol.id
					rol.asociacionFase.append(aso)
				"""note: se anhaden los tipos de item del proyecto que fue asociado"""
				for tipo_item_agregar in posible.tipoItems:
					aso= AsociacionRolTipoItem()
					aso.tipoItem= tipo_item_agregar
					aso.left_id= rol.id
					rol.asociacionTipoItem.append(aso)
	session.add(rol)
	"""
	note: si el rol que esta en el usuario no esta en la vista, se elimina su relacion con el usuario
	"""
	for posible in lista_project:
		if not(posible in lista_vista):
			"""
			note: elimina la asociacion al proyecto (Rol-Proyecto)
			"""
			aso= session.query(AsociacionRolProyecto).filter(and_(AsociacionRolProyecto.left_id == rol.id, AsociacionRolProyecto.right_id == posible.id)).first()
			session.delete(aso)
			"""
			note: elimina las fases asociadas al proyecto (Rol-Fase)
			"""
			for nexo in session.query(AsociacionRolFase).filter_by(left_id= rol.id).all():
				if nexo.fase in posible.fases:
					session.delete(nexo)
			"""
			note: elimina los tipos de item asociados al proyecto (Rol-TipoItem)
			"""
			for nexo in session.query(AsociacionRolTipoItem).filter_by(left_id= rol.id).all():
				if nexo.tipoItem in posible.tipoItems:
					session.delete(nexo)
	output= json.dumps({'success': True})
	return Response(output)


def asignarFases_desdeABMRol(request):
	"""Funcion que se encarga de asignar a un rol una o varias fases
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session = DBSession()
	id_rol= int(request.params['id_rol'])
	lista_fases= request.params['lista_fases']
	lista_fases= lista_fases[1:-1].split(',')
	id_fases= []
	if lista_fases[0] != '':
		for numero in lista_fases:
			id_fases.append(int(numero))
	"""note: obtiene el rol a modificar"""
	rol= session.query(Rol).filter_by(id= id_rol).first()
	lista_vista= []
	lista_actuales= []
	"""note: fases que estan al lado derecho del DRAG"""
	for id_fase in id_fases: 
		fase= session.query(Fase).filter_by(id= id_fase).first()
		lista_vista.append(fase)
	"""note: proyectos que tiene actualmente el rol"""
	for aux in rol.asociacionFase: 
		lista_actuales.append(aux.fase)
	"""note: si la fase de la vista no esta, se crea la relacion y se anhade"""
	for posible in lista_vista: 
		if not (posible in lista_actuales) and posible != None:
			aso= AsociacionRolFase()
			aso.fase= posible
			aso.left_id= rol.id
			rol.asociacionFase.append(aso)
	session.add(rol)
	"""note: si la fase no esta en la vista, se elimina su relacion con el rol"""
	for posible in lista_actuales:
		if not(posible in lista_vista):
			for aso in rol.asociacionFase:
				if aso.fase == posible:
					session.delete(aso)
	output= json.dumps({'success': True})
	return Response(output)


def asignarTiposItem_desdeABMRol(request):
	"""
	Funcion que se encarga de asignar tipo de item a un rol
	:return: retorna al extj un mensaje de si la operacion fue un exito o no
	"""
	session = DBSession()
	id_rol= int(request.params['id_rol'])
	lista_tiposItem= request.params['lista_tiposItem']
	lista_tiposItem= lista_tiposItem[1:-1].split(',')
	id_tiposItem= []
	if lista_tiposItem[0] != '':
		for numero in lista_tiposItem:
			id_tiposItem.append(int(numero))
	"""
	note: obtiene el rol a modificar
	"""
	rol= session.query(Rol).filter_by(id= id_rol).first()
	lista_vista= []
	lista_actuales= []
	"""
	note: tipos de item que estan al lado derecho del DRAG
	"""
	for id_tipo in id_tiposItem: 
		tipo= session.query(TipoItem).filter_by(id= id_tipo).first()
		lista_vista.append(tipo)
	"""
	note: tipos de item que tiene actualmente el rol
	"""
	for aux in rol.asociacionTipoItem: 
		lista_actuales.append(aux.tipoItem)
	"""
	note: si la fase no esta en la vista se crea la relacion y se anhade
	"""
	for posible in lista_vista: 
		if not (posible in lista_actuales) and posible != None:
			aso= AsociacionRolTipoItem()
			aso.tipoItem= posible
			aso.left_id= rol.id
			rol.asociacionTipoItem.append(aso)
	session.add(rol)
	"""
	note: si la fase no esta en la vista, se elimina su relacion
	"""
	for posible in lista_actuales:
		if not(posible in lista_vista):
			for aso in rol.asociacionTipoItem:
				if aso.tipoItem == posible:
					session.delete(aso)
	output= json.dumps({'success': True})
	return Response(output)


def asignarTiposItem_desdeABMProyecto(request):
	"""Funcion que se encarga de asignar tipo de item a un Proyecto
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session = DBSession()
	id_fase= int(request.params['id_fase'])
	lista_tiposItem= request.params['lista_tiposItem']
	lista_tiposItem= lista_tiposItem[1:-1].split(',')
	id_tipos= []
	if lista_tiposItem[0] != '':
		for numero in lista_tiposItem:
			id_tipos.append(int(numero))
	fase= session.query(Fase).filter_by(id= id_fase).first()
	"""
	note: solo el lider de proyecto asignar tipos de item a fases
	"""
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	
	if (usuario != None ):
		if not usuario.esLider(proyecto):
			output= json.dumps({'success': False})
			return Response(output)
	"""
	if proyecto.getEstado() != 'Iniciado':
		output= json.dumps({'success': False})
		return Response(output)
	"""
	lista_vista= []
	lista_actual= []
	for id_tipo in id_tipos: 
		tipo= session.query(TipoItem).filter_by(id= id_tipo).first()
		lista_vista.append(tipo)
	for aux in fase.asociacionTipoItem: 
		lista_actual.append(aux.tipoItem)
	for posible in lista_vista: 
		if not (posible in lista_actual) and posible != None:
			aso= AsociacionFaseTipoItem()
			aso.tipoItem= posible
			aso.left_id= fase.id
			fase.asociacionTipoItem.append(aso)
	for posible in lista_actual:
		if not(posible in lista_vista):
			for aso in fase.asociacionTipoItem:
				if aso.tipoItem == posible:
					session.delete(aso)
	session.add(fase)
	output= json.dumps({'success': True})
	return Response(output)


def crearUsuarios(request):
	"""Funcion que se encarga de crear un usuario
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	post_data= request.POST
	output= json.dumps({'success': False})
	if 'submit' in post_data:
		nombreUsuario= post_data['nombreUsuario']
		password1= post_data['password1']
		nombre= post_data['nombre']
		apellido= post_data['apellido']
		telefono= post_data['telefono']
		if telefono == "":
			telefono= 0
		nroDocumento= post_data['nroDocumento']
		if nroDocumento == "":
			nroDocumento= 0
		mail= post_data['email']
		transaction.begin()
		session= DBSession()
		usuario= Usuario(nombreUsuario, password1, nombre, apellido, telefono, nroDocumento, mail)
		f= open('alpha/static/avatar/usuario.jpg','rb')
		usuario.setImagen(f.read())
		usuario.setNombreImagen('usuario.jpg')
		usuario.setTipoImagen('jpg')
		f.close()
		session.add(usuario)
		transaction.commit()
		output= json.dumps({'success': True})
	return Response(output) 


def eliminarUsuarios(request):
	"""Funcion que se encarga de eliminar un usuario
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	post_data= request.POST
	if 'submit' in post_data:
		session= DBSession()
		idUsuario= int(request.params['id'])
		usuario= session.query(Usuario).filter_by( id= idUsuario).first() 
		output= json.dumps({'success': False})
		en_linea = authenticated_userid(request)
		"""note: comprueba si el usuario existe en el sistema y si no esta loggeado"""
		if usuario.nombreUsuario != en_linea:
			"""note: esta condicion comprueba si el usuario tiene roles
			asociados al mismo y los elimina uno a uno mediante el for """
			for rol in usuario.asociacionRol:
				session.delete(rol)
			session.delete(usuario)
			output= json.dumps({'success': True})
	return Response(output) 


def modificarUsuarios(request):
	"""Funcion que se encarga de modificar un usuario
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	post_data= request.POST
	if 'submit' in post_data:
		session= DBSession()
		idUsuario= int(request.params['id'])
		usuario= session.query(Usuario).filter_by( id= idUsuario).first()
		output= json.dumps({'success': False})
		if usuario != None:
			#usuario.setNombreUsuario(request.params['nombreUsuario'])
			usuario.setNombre(request.params['nombre'])
			usuario.setApellido( request.params['apellido'])
			usuario.setTelefono(request.params['telefono'])
			usuario.setNroDocumento(request.params['nroDocumento'])
			usuario.setMail( request.params['email'])
			session.add(usuario)
			output= json.dumps({'success': True})
	return Response(output)


def crearRol(request):
	"""Funcion que se encarga de crear un rol
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	post_data= request.POST
	if 'submit' in post_data:
		nombreRol= post_data['nombreRol']
		descripcion= post_data['descripcion']
		tipo=  post_data['tipoRol']
		transaction.begin()
		session= DBSession()
		rol= Rol(nombreRol, descripcion)
		rol.setTipo(tipo)
		rol.inicializarPermisos(session)
		session.add(rol)
		transaction.commit()
		output= json.dumps({'success': True})
	return Response(output) 


def eliminarRol(request):
	"""Funcion que se encarga de eliminar un rol
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	post_data= request.POST
	if 'submit' in post_data:
		session= DBSession()
		idRol= int(request.params['id'])
		rol= session.query(Rol).filter_by(id= idRol).first()
		output= json.dumps({'success': False})
		if rol != None:
			if rol.getNombre() == 'Administrador' :
				"""note: retorna False porque no pueden eliminarse estos dos roles"""
				return Response(output)
			"""note: all() retorna una lista, si no hay usuario asociado al rol se continua"""
			listaDeRelacionados=  session.query(AsociacionUsuarioRol).filter_by(right_id= idRol).all()
			if len(listaDeRelacionados) > 0:
				"""note: retorna False porque existen usuarios asociados"""
				return Response(output)
			"""note: elimina las relaciones con Permisos"""
			for relaciones in session.query(AsociacionRolPermiso).filter_by(left_id= rol.id).all(): 
				session.delete(relaciones)
			"""note: elimina las relaciones con Proyectos"""
			for relaciones in session.query(AsociacionRolProyecto).filter_by(left_id= rol.id).all(): 
				session.delete(relaciones)
			"""note: elimina las relaciones con Fases"""
			for relaciones in session.query(AsociacionRolFase).filter_by(left_id= rol.id).all(): 
				session.delete(relaciones)
			"""note: elimina las relaciones con Tipos Items"""
			for relaciones in session.query(AsociacionRolTipoItem).filter_by(left_id= rol.id).all(): 
				session.delete(relaciones)
			"""note: se elimina el rol"""
			session.delete(rol)
			output= json.dumps({'success': True})
	return Response(output)


def modificarRol(request):
	"""Funcion que se encarga de modificar un rol
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	post_data = request.POST
	output = json.dumps({'success': False})
	if 'submit' in post_data:
		session= DBSession()
		idRol= int(request.params['id'])
		rol= session.query(Rol).filter_by(id= idRol).first()
		nombreModificado= False
		descripcionModificado= False
		tipoModificado= False
		if rol != None:
			if rol.getNombre() != request.params['nombreRol']:
				rol.setNombre(request.params['nombreRol'])
				nombreModificado= True
			if rol.getDescripcion() != request.params['descripcion']:
				rol.setDescripcion(request.params['descripcion'])
				descripcionModificado= True
			"""
			if request.params['tipoRol'] != rol.getTipo():
				rol.setTipo(request.params['tipoRol'])
				tipoModificado= True
				rol.inicializarPermisos(session)
				session.add(rol)
			"""
			if nombreModificado or descripcionModificado:
				session.add(rol)
			output= json.dumps({'success': True})
	return Response(output)


def crearProyecto(request):
	"""Funcion que se encarga de crear un proyecto
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	post_data= request.POST
	output= json.dumps({'success': False})
	if 'submit' in post_data:
		nombre= post_data['nombre']
		descripcion= post_data['descripcion']
		transaction.begin()
		session= DBSession()
		proyecto= Proyecto(nombre, descripcion)
		session.add(proyecto)
		proyecto= session.query(Proyecto).filter_by(nombre= nombre).first()
		rolesDeTipoAdministrador= session.query(Rol).filter_by(tipo= 'Administrador').all()
		"""note: asigna el proyecto a todos los roles de tipo Administrador"""
		for rol in rolesDeTipoAdministrador: 
			asociacion= AsociacionRolProyecto()
			asociacion.proyecto= proyecto
			asociacion.left_id= rol.id
			rol.asociacionProyecto.append(asociacion)
			session.add(rol)
		output= json.dumps({'success': True})
		transaction.commit()
	return Response(output) 


def eliminarProyecto(request):
	"""Funcion que se encarga de eliminar un proyecto
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	post_data= request.POST
	if 'submit' in post_data:
		session= DBSession()
		idProyecto= int(request.params['id'])
		proyecto= session.query(Proyecto).filter_by(id= idProyecto).first()
		output= json.dumps({'success': False})
		if proyecto != None:
			for relacion in session.query(AsociacionRolProyecto).filter_by(right_id= proyecto.id).all():
				session.delete(relacion)
			for fase in proyecto.fases:
				for relacion in session.query(AsociacionRolFase).filter_by(right_id= fase.id).all():
					session.delete(relacion)
				"""note: se puede hacer de otra manera, pero funciona asi"""
				for relacion in session.query(AsociacionFaseTipoItem).filter_by(left_id= fase.id).all(): 
					session.delete(relacion)
				session.delete(fase)
			for tipoItem in proyecto.tipoItems:
				for relacion in session.query(AsociacionRolTipoItem).filter_by(right_id= tipoItem.id).all():
					session.delete(relacion)
				for atributo in tipoItem.atributos:
					session.delete(atributo)
				session.delete(tipoItem)
			session.delete(proyecto)
			output= json.dumps({'success': True})
	return Response(output) 


def modificarProyecto(request):
	"""Funcion que se encarga de modificar un proyecto
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	post_data= request.POST
	if 'submit' in post_data:
		session= DBSession()
		idProyecto= int(request.params['id'])
		proyecto= session.query(Proyecto).filter_by(id= idProyecto).first()
		output= json.dumps({'success': False})
		if proyecto != None:
			nombreModificado= False
			descripcionModificado= False
			nroFasesModificado= False
			if proyecto.getNombre() != request.params['nombre']:
				proyecto.setNombre(request.params['nombre'])
				nombreModificado= True
			if proyecto.getDescripcion() != request.params['descripcion']:
				proyecto.setDescripcion(request.params['descripcion'])
				descripcionModificado= True
		if  nombreModificado or descripcionModificado:
			session.add(proyecto)
			output= json.dumps({'success': True})
	return Response(output)


def iniciarProyecto(request):
	"""Funcion que cambia a estado iniciado a un proyecto"""
	session= DBSession()
	proyecto= session.query(Proyecto).filter_by(id= request.params['id']).first()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	output= json.dumps({'success': False})
	if proyecto != None: 
		if proyecto.getEstado() == 'No iniciado' and proyecto.getNroFases() > 0 and proyecto.lider_id != None and usuario.esLider(proyecto):
			proyecto.setEstado('Iniciado')
			for fase in proyecto.fases:
				#fase.setEstado('Desarrollo')
				session.add(fase)
			session.add(proyecto)
			output= json.dumps({'success': True})
	return Response(output)


def terminarProyecto(request):
	"""Funcion que cambia a estado terminado a un proyecto"""
	session= DBSession()
	proyecto= session.query(Proyecto).filter_by(id= request.params['id']).first()
	output= json.dumps({'success': False})
	for fase in proyecto.fases:
		if fase.getEstado() != 'Completa':
			print "\n\n\n\n"
			print "No tiene todas sus fases en estado Completa"
			print "\n\n\n\n"
			return Response(output)
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first() 
	if proyecto != None: 
		if proyecto.getEstado() == 'Iniciado' and usuario.esLider(proyecto):
			proyecto.setEstado('Terminado')
			session.add(proyecto)
			output= json.dumps({'success': True})
	return Response(output)


def crear_fase(request):
	"""Funcion que se encarga de crear una fase
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session= DBSession()
	id_proyecto= int(request.params['idProyectoFase'])
	nombre_fase= request.params['nombreFase']
	descripcion_fase= request.params['descripcion']
	proyecto= session.query(Proyecto).filter_by(id= id_proyecto).first()
	output= json.dumps({'success': False})
	"""
	note: solo el lider de proyecto puede crear fases
	"""
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if not usuario.esLider(proyecto):
		output= json.dumps({'success': False})
		return Response(output)
	if proyecto != None and proyecto.getEstado() == 'No iniciado':
		nuevaFase= Fase(nombre_fase, descripcion_fase)
		proyecto.fases.append(nuevaFase)
		"""note: reordena las fases en su numeracion"""
		proyecto.reEnumerarFases()
		session.add(proyecto)
		proyecto= session.query(Proyecto).filter_by(id= proyecto.id).first()
		fase= proyecto.fases[-1]
		rolesDeTipoAdministrador= session.query(Rol).filter_by(tipo= 'Administrador').all()
		for rol in rolesDeTipoAdministrador: 
			asociacion= AsociacionRolFase()
			asociacion.fase= fase
			asociacion.left_id= rol.id
			rol.asociacionFase.append(asociacion)
			session.add(rol)
		output= json.dumps({'success': True})
	return Response(output)


def eliminar_fase(request):
	"""Funcion que se encarga de eliminar una fase
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session= DBSession()
	id_fase= request.params['id']
	output= json.dumps({'success': False})
	"""note: busca la fase en la BD"""
	fase= session.query(Fase).filter_by(id= id_fase).first()
	if fase != None:
		proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
		"""
		note: solo el lider de proyecto puede eliminar fases
		"""
		en_linea= authenticated_userid(request)
		usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
		if not usuario.esLider(proyecto):
			output= json.dumps({'success': False})
			return Response(output)
		# solo se debe eliminar fases en un proyecto en estado 'Iniciado'
		if proyecto.getEstado() != 'No iniciado':
			output= json.dumps({'success': False})
			return Response(output)
		proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
		# fase.asociacionTipoItem
		for asociacion in session.query(AsociacionFaseTipoItem).filter_by(left_id= fase.id).all():
			session.delete(asociacion) 
		for asociacion in session.query(AsociacionRolFase).filter_by(right_id= fase.id).all():
			session.delete(asociacion) 
		session.delete(fase) 
		proyecto.reEnumerarFases() 
		session.add(proyecto)
		output= json.dumps({'success': True})
	return Response(output)


def modificar_fase(request):
	"""Funcion que se encarga de modifica una fase
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session= DBSession()
	id_fase= request.params['id']
	nombre_fase= request.params['nombreFase']
	descripcion_fase= request.params['descripcion']
	output= json.dumps({'success': False})
	"""note: busca la fase en la BD"""
	fase= session.query(Fase).filter_by(id= id_fase).first()
	"""
	note: solo el lider de proyecto puede crear fases
	"""
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if (usuario != None):
		if not usuario.esLider(proyecto):
			output= json.dumps({'success': False})
			return Response(output)
	if fase != None: 
		nombreModificado= False
		descripcionModificado= False
		if fase.getNombre() != nombre_fase:
			fase.setNombre(nombre_fase)
			nombreModificado= True
		if fase.getDescripcion() != descripcion_fase:
			fase.setDescripcion(descripcion_fase)
			descripcionModificado= True
		if nombreModificado or descripcionModificado:
			session.add(fase)
		output= json.dumps({'success': True})
	return Response(output)


def crear_tipo_item(request):
	"""Funcion que se encarga de crear un tipo de Item
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session= DBSession()
	id_proyecto= int(request.params['idProyecto'])
	nombre_tipo = request.params['nombre']
	descripcion_tipo= request.params['descripcion']
	proyecto= session.query(Proyecto).filter_by(id= id_proyecto).first()
	# solo el lider puede crear tipos de item
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if not usuario.esLider(proyecto):
		output= json.dumps({'success': False})
		return Response(output)
	output= json.dumps({'success': False})
	if proyecto != None:
		nuevo_tipo= TipoItem(nombre_tipo, descripcion_tipo)
		proyecto.tipoItems.append(nuevo_tipo)
		session.add(proyecto)
		"""note: se anhade al rol"""
		proyecto= session.query(Proyecto).filter_by(id= proyecto.id).first()
		tipoItem= proyecto.tipoItems[-1]
		rolesDeTipoAdministrador= session.query(Rol).filter_by(tipo= 'Administrador').all()
		"""note: asigna el tipo item a todos los roles de tipo Administrador"""
		for rol in rolesDeTipoAdministrador: 
			asociacion= AsociacionRolTipoItem()
			asociacion.tipoItem= tipoItem
			asociacion.left_id= rol.id
			rol.asociacionTipoItem.append(asociacion)
			session.add(rol)
		output= json.dumps({'success': True})
	return Response(output) 


def eliminar_tipo_item(request):
	"""Funcion que se encarga de eliminar un tipo de Item
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session= DBSession()
	id_tipo= request.params['id']
	output= json.dumps({'success': False})
	"""note: busca el tipo item en la BD"""
	tipoItem= session.query(TipoItem).filter_by(id= id_tipo).first()
	# solo el lider puede crear tipos de item
	proyecto= session.query(Proyecto).filter_by(id= tipoItem.proyecto_id).first()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if not usuario.esLider(proyecto):
		output= json.dumps({'success': False})
		return Response(output)
	if tipoItem != None: 
		"""note: busca las asociaciones que contienen al tipo, en cuestion"""
		for asociacion in session.query(AsociacionFaseTipoItem).filter_by(right_id= tipoItem.id).all():
			"""note: elimina las posibles asociaciones que pueda tener una fase con un tipo item"""
			session.delete(asociacion) 
		for asociacion in session.query(AsociacionRolTipoItem).filter_by(right_id= tipoItem.id).all():
			"""note: elimina las posibles relaciones que pueda tener con un rol"""
			session.delete(asociacion)
		"""note: elimina los atributos del tipo item"""
		for atributo in tipoItem.atributos:
			session.delete(atributo)
		"""note: elimina el tipo"""
		session.delete(tipoItem) 
		output= json.dumps({'success': True})
	return Response(output)


def modificar_tipo_item(request):
	"""Funcion que se encarga de modificar un tipo de Item
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session= DBSession()
	id_tipo= request.params['id']
	nombre_tipo = request.params['nombre']
	descripcion_tipo= request.params['descripcion']
	output= json.dumps({'success': False})
	"""note: busca la fase en la BD"""
	tipoItem= session.query(TipoItem).filter_by(id= id_tipo).first()
	# solo el lider puede modificar tipos de item
	proyecto= session.query(Proyecto).filter_by(id= tipoItem.proyecto_id).first()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if (usuario != None):
		if not usuario.esLider(proyecto):
			output= json.dumps({'success': False})
			return Response(output)
	if tipoItem != None: 
		nombreModificado= False
		descripcionModificado= False
		if tipoItem.getNombre() != nombre_tipo:
			tipoItem.setNombre(nombre_tipo)
			nombreModificado= True
		if tipoItem.getDescripcion() != descripcion_tipo:
			tipoItem.setDescripcion(descripcion_tipo)
			descripcionModificado= True
		if nombreModificado or descripcionModificado:
			session.add(tipoItem)
		output= json.dumps({'success': True})
	return Response(output)


def importar_tipo_item(request):
	"""Funcion que se encarga de importar un tipo de Item de otros proyectos
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session= DBSession()
	id_proyecto= request.params['id_proyecto']
	lista_tiposItem= request.params['lista_tiposItem']
	lista_tiposItem= lista_tiposItem[1:-1].split(',')
	id_tipos= []
	lista_para_anhadir= []
	if lista_tiposItem[0] != '':
		for numero in lista_tiposItem:
				id_tipos.append(int(numero))
	output= json.dumps({'success': False})
	for id_tipo in id_tipos:
		tipoItem= session.query(TipoItem).filter_by(id= id_tipo).first()
		lista_para_anhadir.append(tipoItem)
	"""
	note: solo el lider de proyecto puede importar tipos de item
	"""
	proyecto= session.query(Proyecto).filter_by(id= id_proyecto).first()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if (usuario != None):
		if not usuario.esLider(proyecto):
			output= json.dumps({'success': False})
			return Response(output)
	rolesDeTipoAdministrador= session.query(Rol).filter_by(tipo= 'Administrador').all()
	if proyecto != None:
		for tipoItem in lista_para_anhadir:
			nuevoTipoItem= TipoItem(tipoItem.getNombre(), tipoItem.getDescripcion())
			nuevoTipoItem.setDescripcion(tipoItem.getDescripcion())
			nuevoTipoItem.importarAtributos(tipoItem.getAtributos())
			proyecto.tipoItems.append(nuevoTipoItem)
			session.add(proyecto)
			proyecto= session.query(Proyecto).filter_by(id= proyecto.id).first()
			nuevoTipoItem= proyecto.tipoItems[-1]
			for rol in rolesDeTipoAdministrador: 
				asociacion= AsociacionRolTipoItem()
				asociacion.tipoItem= nuevoTipoItem
				asociacion.left_id= rol.id
				rol.asociacionTipoItem.append(asociacion)
				session.add(rol)
		output= json.dumps({'success': True})
	return Response(output)


def importar_fases(request):
	session = DBSession()
	id_proyecto= int(request.params['id_proyecto'])
	"""
	note: no se pueden agregar fases a un proyecto cuyo lider dio la operacion 'iniciar' al mismo
	"""
	proyecto= session.query(Proyecto).filter_by(id= id_proyecto).first()
	if proyecto.getEstado() != 'No iniciado':
		output= json.dumps({'success': False})
		return Response(output)
	"""
	note: solo el lider de este proyecto puede importar fases
	"""
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if (usuario != None):
		if not usuario.esLider(proyecto):
			output= json.dumps({'success': False})
			return Response(output)
	"""
	note: lista en forma de cadena enviada por el extjs
	"""
	lista_fases= request.params['lista_fases']
	lista_fases= lista_fases[1:-1].split(',')
	id_fases= []
	"""
	note: se extraen los datos (cadenas) mandados por la aplicacion extjs
	"""
	if lista_fases[0] != '':
		for numero in lista_fases:
			id_fases.append(int(numero))
	lista_fases_agregar= []
	lista_tipos_agregar= []
	diccionario_tipos= {}
	diccionario_fases= {}
	"""
	note: fases que se encuentran al lado derecho del 'DRAG'
	"""
	for id_fase in id_fases: 
		fase= session.query(Fase).filter_by(id= id_fase).first()
		lista_fases_agregar.append(fase)
	"""
	note: tipos de items relacionados a las fases, que se encuentran al lado derecho de 'DRAG'
	"""
	for fase in lista_fases_agregar:
		for relacion in fase.asociacionTipoItem:
			if not( relacion.tipoItem in lista_tipos_agregar ):
				lista_tipos_agregar.append(relacion.tipoItem)
	"""
	note: agrega los tipos de items al proyecto
	"""
	rolesDeTipoAdministrador= session.query(Rol).filter_by(tipo= 'Administrador').all()
	for agregar in lista_tipos_agregar:
		nuevoTipo= TipoItem(agregar.getNombre(), agregar.getDescripcion())
		nuevoTipo.setDescripcion(agregar.getDescripcion())
		nuevoTipo.importarAtributos(agregar.getAtributos())
		proyecto.tipoItems.append(nuevoTipo)
		session.add(proyecto)
		aux= session.query(TipoItem).order_by(TipoItem.id)
		diccionario_tipos[agregar]= aux[-1] # ultimo tipo item anhadido
		for rol in rolesDeTipoAdministrador: 
			asociacion= AsociacionRolTipoItem()
			asociacion.tipoItem= aux[-1]
			asociacion.left_id= rol.id
			rol.asociacionTipoItem.append(asociacion)
			session.add(rol)
	"""
	note: agrega las fases al proyecto
	"""
	for agregar in lista_fases_agregar:
		nuevaFase= Fase(agregar.getNombre(), agregar.getDescripcion())
		proyecto.fases.append(nuevaFase)
		session.add(proyecto)
		aux= session.query(Fase).order_by(Fase.id)
		diccionario_fases[agregar]= aux[-1] # ultima fase anhadida
		for rol in rolesDeTipoAdministrador: 
			asociacion= AsociacionRolFase()
			asociacion.fase= aux[-1]
			asociacion.left_id= rol.id
			rol.asociacionFase.append(asociacion)
			session.add(rol)
	proyecto.reEnumerarFases()
	session.add(proyecto)
	"""
	note: agrega la relacion (enlaza) las fases con los tipos de item
	"""
	for fase in lista_fases_agregar:
		fase_real= diccionario_fases[fase]
		for nexo in fase.asociacionTipoItem:
			tipo_real= diccionario_tipos[nexo.tipoItem]
			asociacion= AsociacionFaseTipoItem()
			asociacion.tipoItem= tipo_real
			asociacion.left_id= fase_real.id
			fase_real.asociacionTipoItem.append(asociacion)
			session.add(fase_real)
	output= json.dumps({'success': True})
	return Response(output)


def crear_atributo(request):
	session = DBSession()
	idTipoItem= int(request.params['idTipoItem'])
	nombre= request.params['nombreAtributo']
	descripcion= request.params['descripcion']
	tipo= request.params['tipo']
	valor= request.params['valor']
	tipoItem= session.query(TipoItem).filter_by(id= idTipoItem).first()
	"""
	note: solo el lider de este proyecto puede importar fases
	"""
	proyecto= session.query(Proyecto).filter_by(id= tipoItem.proyecto_id).first()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if not usuario.esLider(proyecto):
		output= json.dumps({'success': False})
		return Response(output)
	nuevoAtributo= Atributo(nombre, tipo)
	nuevoAtributo.setDescripcion(descripcion)
	nuevoAtributo.setValor(valor)
	tipoItem.atributos.append(nuevoAtributo)
	session.add(tipoItem)
	# actualiza todos los atributos de los items que tienen ese tipo de item
	lista_items= session.query(Item).filter_by(tipoItem_id= tipoItem.id).all()
	for item in lista_items:
		item.actualizarAtributos()
		session.add(item)
	output= json.dumps({'success': True})
	return Response(output)


def modificar_atributo(request):
	session = DBSession()
	idAtributo= int(request.params['id'])
	nombre= request.params['nombreAtributo']
	descripcion= request.params['descripcion']
	valor= request.params['valor']
	atributo= session.query(Atributo).filter_by(id= idAtributo).first()
	nombreModificado= False
	descripcionModificado= False
	valorModificado= False
	if(atributo.getNombre() != nombre):
		atributo.setNombre(nombre)
		nombreModificado= True
	if(atributo.getDescripcion() != descripcion):
		atributo.setDescripcion(descripcion)
		descripcionModificado= True
	if(atributo.getValor() != valor):
		atributo.setValor(valor)
		valorModificado= True
	if(nombreModificado or descripcionModificado or valorModificado):
		session.add(atributo)
	output= json.dumps({'success': True})
	return Response(output)

#ordenado
def crear_item(request):
	session = DBSession()
	idFase= int(request.params['idFase'])
	nombre=  request.params['nombre']
	complejidad= int(request.params['complejidad'])
	# la complejidad debe estar entre 1 y 10
	if complejidad > 10 or complejidad < 1:
		output= json.dumps({'success': False})
		return Response(output)
	descripcion= request.params['descripcion']
	idTipoItem= int(request.params['tipoItem'])
	fase= session.query(Fase).filter_by(id= idFase).first()
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	if proyecto.getEstado() != 'Iniciado':
		output= json.dumps({'success': False})
		return Response(output)
	tipoItem= session.query(TipoItem).filter_by(id= idTipoItem).first()
	item= Item(nombre, complejidad, descripcion)
	item.tipoItem= tipoItem
	item.inicializarAtributos()
	fase.items.sort(compara)
	fase.items.append(item)
	fase.reEnumerarItems()
	fase.reEnumerarItemsPorTipo()
	fase.actualizarEstado()
	session.add(fase)
	""" note: seccion historial"""
	item= session.query(Item).order_by(Item.id)[-1]
	historial= Historial("Creacion del item")
	historial.generarHistorial(item, session, request)
	output= json.dumps({'success': True})
	return Response(output)


def crear_item2(request):
	session = DBSession()
	idFase= int(request.params['idFase'])
	nombre=  request.params['nombre']
	complejidad= int(request.params['complejidad'])
	descripcion= request.params['descripcion']
	idTipoItem= int(request.params['tipoItem'])
	tipoItem= session.query(TipoItem).filter_by(id= idTipoItem).first()
	
	fase= session.query(Fase).filter_by(id= idFase).first()
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	if proyecto.getEstado() != 'Iniciado':
		output= json.dumps({'success': False, 'mensaje': 'Error: solo se pueden crear items en proyectos con estado Iniciado'})
		return Response(output)
	# la complejidad debe estar entre 1 y 10
	if complejidad > 10 or complejidad < 1:
		output= json.dumps({'success': False, 'mensaje':'Error: el valor de la complejidad debe estar entre 1 y 10'})
		return Response(output)
	item= Item(nombre, complejidad, descripcion)
	item.tipoItem= tipoItem
	#item.inicializarAtributos()
	cont= 1
	for atributoImportado in range(0, tipoItem.getNroAtributos()):
		tipo= 'tipo'+str(cont)
		nombre= 'label'+ str(cont)
		valor= 'atrib'+ str(cont)
		tipo= request.params[tipo]
		nombre= request.params[nombre]
		valor= request.params[valor]
		nuevoAtributo= Atributo(nombre, tipo)
		nuevoAtributo.setDescripcion(" ")
		nuevoAtributo.setValor(valor)
		item.atributos.append(nuevoAtributo)
		cont= cont + 1
	fase.items.sort(compara)
	fase.items.append(item)
	fase.reEnumerarItems()
	fase.reEnumerarItemsPorTipo()
	fase.actualizarEstado()
	session.add(fase)
	""" note: seccion historial"""
	item= session.query(Item).order_by(Item.id)[-1]
	historial= Historial("Creacion del item")
	historial.generarHistorial(item, session, request)
	output= json.dumps({'success': True, 'mensaje':'El item ha sido creado en la fase'})
	return Response(output)


#ordenado-lb
def modificar_item(request):
	session = DBSession()
	idItem= int(request.params['id'])
	nombre=  request.params['nombre']
	complejidad= int(request.params['complejidad'])
	descripcion= request.params['descripcion']
	"""
	note: comprueba la complejidad del item
	"""
	if complejidad > 10 or complejidad < 1:
		output= json.dumps({'success': False, 'mensaje': 'Error: la complejidad debe estar entre 1 y 10'})
		return Response(output)
	item= session.query(Item).filter_by(id= idItem).first()
	paraLb= item
	if item.getEstado() == 'Bloqueado':
		print "\n\n\n\n\n\n imposible, esta en una linea base cerrada \n\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje': 'Error: imposible, esta en una linea base cerrada'})
		return Response(output)
	if item.getComplejidad() != complejidad or item.getDescripcion() != descripcion or item.getNombre() != nombre:
		fase= session.query(Fase).filter_by(id= item.fase_id).first()
		nuevaVersion= Item(nombre, complejidad, descripcion)
		nuevaVersion.tipoItem= item.tipoItem
		nuevaVersion.copiarAtributos(item.getAtributos(), item.getRelacionArchivos())
		nuevaVersion.setVersion(item.getVersion() + 1)
		nuevaVersion.versionAnterior.append(item)
		nuevaVersion.setEstado('Revision')
		"""
		note: guarda la nueva version
		"""
		session.add(nuevaVersion)
		nuevaVersion= session.query(Item).order_by(Item.id)[-1]
		nuevaVersion= nuevaVersion.copiarRelaciones(item, session)
		session.add(nuevaVersion)
		"""
		note: actualiza la fase
		"""
		fase.actualizarFase(session, item, nuevaVersion)
		"""
		note: seccion historial
		"""
		item= session.query(Item).order_by(Item.id)[-1]
		historial= Historial("Modificacion de atributos genericos")
		historial.generarHistorial(item, session, request)
		## agregado para lineas base
		paraLb= session.query(Item).filter_by(id= paraLb.id).first()
		if paraLb.tieneLineaBase(): # si el item posee linea base se elimina la version anterior
			item= session.query(Item).filter_by(id= item.id).first()
			lb= paraLb.getLineaBase(session)
			lb.actualizarLineaBase(session, paraLb, item) # funcion que remueve la version anterior y pone la actual
	output= json.dumps({'success': True, 'mensaje':'Se ha modificado con exito el atributo'})
	return Response(output)

#ordenado-lb
def modificar_atributo_item(request):
	session = DBSession()
	idAtributo= int(request.params['id'])
	nombre= request.params['nombreAtributo']
	descripcion= request.params['descripcion']
	valor= request.params['valor']
	atributo= session.query(Atributo).filter_by(id= idAtributo).first()
	item= session.query(Item).filter_by(id= atributo.item_id).first()
	paraLb= item
	if item.getEstado() == 'Bloqueado':
		print "\n\n\n\n\n\n imposible, esta en una linea base cerrada \n\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje': 'Error: imposible, esta en una linea base cerrada'})
		return Response(output)
	if atributo.getNombre() != nombre or atributo.getDescripcion() != descripcion or valor != atributo.getValor():
		fase= session.query(Fase).filter_by(id= item.fase_id).first()
		fase.items.sort(compara)
		nuevaVersion= Item(item.getNombre() ,item.getComplejidad(), item.getDescripcion())
		nuevaVersion.tipoItem= item.tipoItem
		nuevaVersion.modificarAtributo(item.getAtributos(), atributo, nombre, descripcion, valor, item.getRelacionArchivos())
		nuevaVersion.setVersion(item.getVersion() + 1)
		nuevaVersion.versionAnterior.append(item)
		nuevaVersion.setEstado('Revision')
		##### seccion que enlaza todas las relaciones habidas por haber
		session.add(nuevaVersion)
		nuevaVersion= session.query(Item).order_by(Item.id)[-1]
		nuevaVersion.copiarRelaciones(item, session)
		session.add(nuevaVersion)
		#####
		indice= fase.items.index(item)
		fase.items.insert(indice, nuevaVersion)
		fase.items.remove(item)
		fase.reEnumerarItems()
		fase.reEnumerarItemsPorTipo()
		session.add(fase)
		""" note: seccion historial"""
		item= session.query(Item).order_by(Item.id)[-1]
		en_linea= authenticated_userid(request)
		usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
		historial= Historial("Modificacion de atributos de Tipo")
		historial.item= item
		historial.usuario= usuario
		session.add(historial)
		## agregado para lineas base
		paraLb= session.query(Item).filter_by(id= paraLb.id).first()
		if paraLb.tieneLineaBase(): # si el item posee linea base se elimina la version anterior
			item= session.query(Item).filter_by(id= item.id).first()
			lb= paraLb.getLineaBase(session)
			lb.actualizarLineaBase(session, paraLb, item) # funcion que remueve la version anterior y pone la actual
	output= json.dumps({'success': True, 'mensaje':'Se ha modificado con exito el atributo'})
	return Response(output)

#1107
def modificar_atributo_item2(request):
	session = DBSession()
	idItem= int(request.params['id_item'])
	item= session.query(Item).filter_by(id= idItem).first()
	paraLb= item
	if item.getEstado() == 'Bloqueado':
		print "\n\n\n\n\n\n imposible, esta en una linea base cerrada \n\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje': 'Error: imposible, esta en una linea base cerrada'})
		return Response(output)
	huboModificacion= False
	nombreItem=  request.params['nombre']
	complejidadItem= int(request.params['complejidad'])
	descripcionItem= request.params['descripcion']
	if item.getComplejidad() != complejidadItem or item.getDescripcion() != descripcionItem or item.getNombre() != nombreItem:
		huboModificacion= True
	cont= 1
	for atributoImportado in range(0, len(item.atributos)):
		idAtributo= 'id'+str(cont)
		tipo= 'tipo'+str(cont)
		nombre= 'label'+ str(cont)
		valor= 'atrib'+ str(cont)
		idAtributo= int(request.params[idAtributo])
		tipo= request.params[tipo]
		nombre= request.params[nombre]
		valor= str(request.params[valor])
		atributo= session.query(Atributo).filter_by(id= idAtributo).first()
		if (atributo.getNombre() != nombre) or (valor != str(atributo.getValor())):
			print "\n\n\n\n"
			print atributo.getNombre()
			print "\n\n\n\n"
			print nombre
			print "\n\n\n\n"
			print atributo.getValor()
			print "\n\n\n\n"
			print valor
			print "\n\n\n\n"
			huboModificacion= True
		cont= cont + 1
	if huboModificacion :
		fase= session.query(Fase).filter_by(id= item.fase_id).first()
		nuevaVersion= Item(nombreItem, complejidadItem, descripcionItem)
		nuevaVersion.tipoItem= item.tipoItem
		nuevaVersion.copiarArchivos(item.getRelacionArchivos())
		cont= 1
		for atributoImportado in range(0, len(item.atributos)):
			tipo= 'tipo'+str(cont)
			nombre= 'label'+ str(cont)
			valor= 'atrib'+ str(cont)
			tipo= request.params[tipo]
			nombre= request.params[nombre]
			valor= request.params[valor]
			nuevoAtributo= Atributo(nombre, tipo)
			nuevoAtributo.setDescripcion(" ")
			nuevoAtributo.setValor(valor)
			nuevaVersion.atributos.append(nuevoAtributo)
			cont= cont + 1
		nuevaVersion.setVersion(item.getVersion() + 1)
		nuevaVersion.versionAnterior.append(item)
		nuevaVersion.setEstado('Revision')
		##### seccion que enlaza todas las relaciones habidas por haber
		session.add(nuevaVersion)
		nuevaVersion= session.query(Item).order_by(Item.id)[-1]
		nuevaVersion.copiarRelaciones(item, session)
		session.add(nuevaVersion)
		#####
		fase.actualizarFase(session, item, nuevaVersion)
		item= session.query(Item).order_by(Item.id)[-1]
		en_linea= authenticated_userid(request)
		usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
		historial= Historial("Modificacion de atributos de Tipo")
		historial.item= item
		historial.usuario= usuario
		session.add(historial)
		## agregado para lineas base
		paraLb= session.query(Item).filter_by(id= paraLb.id).first()
		if paraLb.tieneLineaBase(): # si el item posee linea base se elimina la version anterior
			item= session.query(Item).filter_by(id= nuevaVersion.id).first()
			lb= paraLb.getLineaBase(session)
			lb.actualizarLineaBase(session, paraLb, item) # funcion que remueve la version anterior y pone la actual
		output= json.dumps({'success': True, 'mensaje':'Se ha modificado con exito el atributo'})
	else:
		output= json.dumps({'success': True, 'mensaje':'No se ha realizado ningun cambio, no hay cambio de version'})
	return Response(output)

#ordenado-lb
def eliminar_item(request):
	session = DBSession()
	idItem= int(request.params['id'])
	item= session.query(Item).filter_by(id= idItem).first()
	if item.getEstado() == 'Bloqueado':
		print "\n\n\n\n\n\n imposible, esta en una linea base cerrada \n\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje':'Error: el item no puede ser eliminado porque esta en una linea base cerrada'})
		return Response(output)
	fase= session.query(Fase).filter_by(id= item.fase_id).first()
	item.setEstado('Eliminado')
	session.add(item)
	fase.items.sort(compara)
	fase.reEnumerarItems()
	fase.reEnumerarItemsPorTipo()
	fase.actualizarEstado()
	session.add(fase)
	""" note: seccion historial, genera del historial del item a eliminar"""
	item= session.query(Item).filter_by(id= item.id).first()
	historial= Historial("Eliminacion del item")
	historial.generarHistorial(item, session, request)
	if item.tieneLineaBase():
		lb= item.getLineaBase(session)
		lb.items.remove(item)
		session.add(lb)
		if lb.estaVacia():
			session.delete(lb)
	output= json.dumps({'success': True, 'mensaje':'El item ha sido eliminado de la fase'})
	return Response(output)

#ordenado-lb
def revertir_item(request):
	session = DBSession()
	idAnterior= int(request.params['id'])
	idActual= int(request.params['idRevertido'])
	"""note: item que actualmente esta en vigencia"""
	itemActual= session.query(Item).filter_by(id= idActual).first()
	paraLb= itemActual # para actualizar la linea base del itemActual, si posee alguna
	if itemActual.getEstado() == 'Bloqueado':
		print "\n\n\n\n\n\n imposible, esta en una linea base cerrada \n\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje':'Error: el item no puede ser eliminado porque esta en una linea base cerrada'})
		return Response(output)
	"""note: item que se quiere poner en vigencia"""
	itemCandidato= session.query(Item).filter_by(id= idAnterior).first()
	fase= session.query(Fase).filter_by(id= itemActual.fase_id).first()
	"""
	note: filtro que controla que al revivir el item, algun item de la fase tenga dos padres (uno de ellos el item a revivir)
	"""
	hijos_del_muerto= []
	for relacion in itemCandidato.relacionHijo:
		if (relacion.hijo in fase.items) and (relacion.hijo.getEstado() != 'Eliminado'):
			hijos_del_muerto.append(relacion.hijo)
	for item_aux in fase.items:
		if (item_aux != itemActual) and (item_aux.getEstado() != 'Eliminado'):
			for relacion in item_aux.relacionHijo:
				if relacion.hijo.getEstado() != 'Eliminado' and (relacion.hijo in hijos_del_muerto):
					print "\n\n\n\n\n\n\n\n"
					print "si se revierte existirian dos padres, esto no puede ser"
					print "\n\n\n\n\n\n\n\n"
					output= json.dumps({'success': False, 'mensaje': 'Error: si se revierte existirian dos padres, esto no puede ser'})
					return Response(output)
	"""
	note: el padre del item a promover para ser revertido
	"""
	###
	fase= session.query(Fase).filter_by(id= itemActual.fase_id).first()
	nuevaVersion= Item(itemCandidato.getNombre(), itemCandidato.getComplejidad(), itemCandidato.getDescripcion())
	nuevaVersion.tipoItem= itemCandidato.tipoItem
	nuevaVersion.copiarAtributos(itemCandidato.getAtributos(), itemCandidato.getRelacionArchivos())
	nuevaVersion.setVersion(itemActual.getVersion() + 1)
	nuevaVersion.versionAnterior.append(itemActual)
	nuevaVersion.setEstado('Revision')
	"""
	note: guarda la nueva version
	"""
	session.add(nuevaVersion)
	nuevaVersion= session.query(Item).order_by(Item.id)[-1]
	nuevaVersion= nuevaVersion.copiarRelacionesParaRevertir(itemCandidato, itemActual.fase_id, session)
	session.add(nuevaVersion)
	"""
	note: actualiza la fase
	"""
	fase.actualizarFase(session, itemActual, nuevaVersion)
	fase.actualizarEstado()
	session.add(fase)
	"""
	note: seccion historial
	"""
	item= session.query(Item).order_by(Item.id)[-1]
	historial= Historial("Se ha revertido el item, con nueva version")
	historial.generarHistorial(item, session, request)
	## agregado para lineas base
	paraLb= session.query(Item).filter_by(id= paraLb.id).first()
	if paraLb.tieneLineaBase(): # si el item posee linea base se elimina la version anterior
		item= session.query(Item).filter_by(id= item.id).first()
		lb= paraLb.getLineaBase(session)
		lb.actualizarLineaBase(session, paraLb, item)
	output= json.dumps({'success': True, 'mensaje': 'El item ha sido revertido a una version anterior'})
	return Response(output)

#ordenado-lb
def relacionar_antecesor(request):
	session= DBSession()
	id_item= int(request.params['id_item'])
	lista_Item= request.params['lista_Item']
	lista_Item= lista_Item[1:-1].split(',')
	id_items= []
	output= json.dumps({'success': True, 'mensaje': 'El item ha sido relacionado con exito'})
	"""
	note: lista_Item contiene todos los ids de los items mandados, en el DRAG derecho para asignar
	"""
	if lista_Item[0] != '':
		for numero in lista_Item:
			id_items.append(int(numero))
	"""
	note: items del lado derecho del DRAG
	"""
	lista_vista= []
	for id_aux in id_items:
		item= session.query(Item).filter_by(id= id_aux).first()
		lista_vista.append(item)
	# comprueba que cada item este en una LB cerrada
	for candi in lista_vista:
		if candi.getEstado() != 'Bloqueado':
			output= json.dumps({'success': False, 'mensaje': 'Error: alguno de los items seleccionado para la relacion no esta en una linea base cerrada'})
			return Response(output)
	
	
	item= session.query(Item).filter_by(id= id_item).first()
	paraLb= item # para la linea base
	if item.getEstado() == 'Bloqueado':
		print "\n\n\n\n\n\n imposible, esta en una linea base cerrada \n\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje': 'Error: imposible, esta en una linea base cerrada'})
		return Response(output)
	fase= session.query(Fase).filter_by(id= item.fase_id).first()
	faseActual= fase
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	proyecto.fases.sort(comparaFase)
	ubicacion= proyecto.fases.index(fase)
	""" 
	note si la fase del item es la primera, no se puede asignar antecesor
	"""
	
	if ubicacion == 0:
		output= json.dumps({'success': False,'mensaje': 'Error: el item es la primera, no se puede asignar antecesor' })
		return Response(output)
	
	""" 
	note: items antecesores relacionados actualmente, que estan en la fase anterior y no estan eliminados
	"""
	fase= proyecto.fases[ubicacion - 1]
	lista_actual= []
	for relacion in session.query(RelacionSucesor).filter_by(right_id= item.id).all():
		item_aux= session.query(Item).filter_by(id= relacion.left_id).first()
		if item_aux.getEstado() != 'Eliminado' and (item_aux in fase.items):
			lista_actual.append(item_aux)
	"""
	note: asignacion de relaciones, si es que no ya existian
	"""
	###
	nuevaVersion= Item(item.getNombre(), item.getComplejidad(), item.getDescripcion())
	nuevaVersion.tipoItem= item.tipoItem
	nuevaVersion.copiarAtributos(item.getAtributos(), item.getRelacionArchivos())
	nuevaVersion.setVersion(item.getVersion() + 1)
	nuevaVersion.versionAnterior.append(item)
	nuevaVersion.setEstado('Revision')
	"""
	note: guarda la nueva version
	"""
	session.add(nuevaVersion)
	nuevaVersion= session.query(Item).order_by(Item.id)[-1]
	nuevaVersion= nuevaVersion.copiarRelaciones(item, session)
	itemAn= nuevaVersion # para la linea base
	session.add(nuevaVersion)
	"""
	note: actualiza la fase
	"""
	faseActual.actualizarFase(session, item, nuevaVersion)
	historial= Historial("Se ha modificado relaciones antecesor")
	historial.generarHistorial(nuevaVersion, session, request)
	###
	for posible in lista_vista:
		"""
		note: si el item ya esta relacionado se rechaza, si no se crea una relacion y anhade
		"""
		if not (posible in lista_actual) and posible != None:
			aso= RelacionSucesor()
			aso.item= nuevaVersion
			aso.left_id= posible.id
			posible.relacionSucesor.append(aso)
			session.add(posible)
	for posible in lista_actual:
		"""
		note: si el item ya no se encuentra relacionado se elimina la relacion
		"""
		if not(posible in lista_vista):
			for relacion in posible.relacionSucesor:
				if relacion.item == nuevaVersion:
					session.delete(relacion)
	
	## agregado para lineas base
	paraLb= session.query(Item).filter_by(id= paraLb.id).first()
	if paraLb.tieneLineaBase(): # si el item posee linea base se elimina la version anterior
		itemAn= session.query(Item).filter_by(id= itemAn.id).first()
		lb= paraLb.getLineaBase(session)
		lb.actualizarLineaBase(session, paraLb, itemAn)
	return Response(output)

#ordenado-lb
def relacionar_padre(request):
	session = DBSession()
	id_item= int(request.params['id_item'])
	lista_Item= request.params['lista_Item']
	lista_Item= lista_Item[1:-1].split(',')
	id_item_vista= None
	if lista_Item[0] != '':
		id_item_vista= int(lista_Item[0])
	""" note: item actual """
	itemActual= session.query(Item).filter_by(id= id_item).first()
	paraLb= itemActual
	if itemActual.getEstado() == 'Bloqueado':
		print "\n\n\n\n\n\n imposible, esta en una linea base cerrada \n\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje': 'Error: imposible, esta en una linea base cerrada'})
		return Response(output)
	""" note: item del lado derecho del DRAG, que se quiere asignar como Padre """
	itemCandidato= session.query(Item).filter_by(id= id_item_vista).first()
	""" note: fase actual """
	fase= session.query(Fase).filter_by(id= itemActual.fase_id).first()
	padreActual= itemActual.getPadre(fase)
	""" note: Proyecto Actual """
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	###### segmento de codigo que recopila los tipos de item de acuerdo al rol del usuario
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	tipos_asociado_fase= []
	lista_tipos_roles= []
	for relacion in fase.asociacionTipoItem:
		tipos_asociado_fase.append(relacion.tipoItem)
	if usuario.esLider(proyecto):
		for tipoItem in proyecto.tipoItems:
			lista_tipos_roles.append(tipoItem)
	for asociacion in usuario.asociacionRol:
		rol= asociacion.rol
		for relacion in rol.asociacionTipoItem:
			tipoItem= relacion.tipoItem
			if not(tipoItem in lista_tipos_roles) and (tipoItem in proyecto.tipoItems):
				lista_tipos_roles.append(tipoItem)
	######
	""" note: controla si el item tiene un padre que no se puede ver porque no se posee el Rol de su tipo """
	for item_aux in fase.items:
		if item_aux != itemActual and item_aux.getEstado() != 'Eliminado' and not(item_aux.tipoItem in lista_tipos_roles) and (item_aux.tipoItem in tipos_asociado_fase):
			for relacion in item_aux.relacionHijo :
				if relacion.hijo == itemActual :
					output= json.dumps({'success': False, 'mensaje': 'Imposible, posee un padre invisible, item que no ves por tu rol'})
					return Response(output)
	""" note:  """
	##*******
	if not itemActual.tienePadre(fase):
		if itemCandidato != None:
			if itemCandidato.getEstado() != 'Aprobado':
				output= json.dumps({'success': False, 'mensaje': 'Error: el item que se quiere asignar como padre no esta en estado Aprobado'})
				return Response(output)
		if itemCandidato != None:
			if itemActual.esDescendiente(fase, itemCandidato):
				output= json.dumps({'success': False, 'mensaje': 'Error: el item seleccionado a ser padre es un descendiente (hijo, nieto, etc), esto no puede ser (se formaria un ciclo)'})
				return Response(output)
		if itemCandidato == None:
			output= json.dumps({'success': True, 'mensaje': 'No hubo cambios en la relacion'})
			return Response(output)
	elif itemActual.tienePadre(fase):
		if itemActual.getPadre(fase) == itemCandidato :
			if (itemCandidato.getEstado() == 'Aprobado' or itemCandidato.getEstado() == 'Bloqueado'):
				output= json.dumps({'success': False, 'mensaje': 'No hubo cambios en la relacion'})
				return Response(output)
			else:
				output= json.dumps({'success': False, 'mensaje': 'Error: existe inconsistencia del sistema, el padre actual del item no esta en estado Aprobado, conviene desasignarlo'})
				return Response(output)
		if itemCandidato != None:
			if itemCandidato.getEstado() != 'Aprobado':
				output= json.dumps({'success': False, 'mensaje': 'Error: el item que se quiere asignar como padre no esta en estado Aprobado'})
				return Response(output)
		if itemCandidato != None:
			if itemActual.esDescendiente(fase, itemCandidato):
				output= json.dumps({'success': False, 'mensaje': 'Error: el item seleccionado a ser padre es un descendiente (hijo, nieto, etc), esto no puede ser (se formaria un ciclo)'})
				return Response(output)
	
	nuevaVersion= Item(itemActual.getNombre(), itemActual.getComplejidad(), itemActual.getDescripcion())
	nuevaVersion.tipoItem= itemActual.tipoItem
	nuevaVersion.setEstado('Revision')
	nuevaVersion.copiarAtributos(itemActual.getAtributos(), itemActual.getRelacionArchivos())
	nuevaVersion.setVersion(itemActual.getVersion() + 1)
	nuevaVersion.versionAnterior.append(itemActual)
	"""
	note: guarda la nueva version
	"""
	session.add(nuevaVersion)
	nuevaVersion= session.query(Item).order_by(Item.id)[-1]
	nuevaVersion= nuevaVersion.copiarRelaciones(itemActual, session)
	itemAn= nuevaVersion
	session.add(nuevaVersion)
	"""
	note: actualiza la fase
	"""
	fase.actualizarFase(session, itemActual, nuevaVersion)
	historial= Historial("Se ha modificado relaciones padres")
	historial.generarHistorial(nuevaVersion, session, request)
	###
	
	
	if padreActual != None and itemCandidato == None:
		"""
		note: caso si el DRAG derecho esta vacio y existe actualmente padre
		"""
		relacion= session.query(RelacionHijo).filter(and_(RelacionHijo.left_id == padreActual.id, RelacionHijo.right_id == nuevaVersion.id)).one()
		session.delete(relacion)
		output= json.dumps({'success': True, 'mensaje': 'El padre actual ha sido removido con exito'})
	elif padreActual == None and itemCandidato != None:
		"""
		note: caso si el DRAG derecho no esta vacio y no existe actualmente padre
		"""
		relacion= RelacionHijo()
		relacion.hijo= nuevaVersion
		relacion.left_id= itemCandidato.id
		itemCandidato.relacionHijo.append(relacion)
		session.add(itemCandidato)
		output= json.dumps({'success': True, 'mensaje': 'Se ha asignado un padre con exito'})
	else:
		"""
		note: existe un Padre y el lado derecho del Drag no esta vacio
		"""
		relacion= RelacionHijo()
		relacion.hijo= nuevaVersion
		relacion.left_id= itemCandidato.id
		itemCandidato.relacionHijo.append(relacion)
		session.add(itemCandidato)
		relacion= session.query(RelacionHijo).filter(and_(RelacionHijo.left_id == padreActual.id, RelacionHijo.right_id == nuevaVersion.id)).first()
		session.delete(relacion)
		output= json.dumps({'success': True, 'mensaje': 'Se intercambiado de padre correctamente'})
	## agregado para lineas base
	paraLb= session.query(Item).filter_by(id= paraLb.id).first()
	if paraLb.tieneLineaBase(): # si el item posee linea base se elimina la version anterior
		itemAn= session.query(Item).filter_by(id= itemAn.id).first()
		lb= paraLb.getLineaBase(session)
		lb.actualizarLineaBase(session, paraLb, itemAn)
	return Response(output)


def relacionar_hijo(request):
	"""
	session = DBSession()
	id_item= int(request.params['id_item'])
	lista_Item= request.params['lista_Item']
	lista_Item= lista_Item[1:-1].split(',')
	#note: item seleccionado para atribuirle relaciones
	itemActual= session.query(Item).filter_by(id= id_item).first() # item actual
	fase= session.query(Fase).filter_by(id= itemActual.fase_id).first() # fase en que se encuentra el item a relacionar
	id_item_vista= []
	if lista_Item[0] != '':
		for numero in lista_Item:
			id_item_vista.append(int(numero))
	#note: items del lado derecho del DRAG
	lista_vista= []
	for id_aux in id_item_vista:
		item= session.query(Item).filter_by(id= id_aux).first()
		lista_vista.append(item)
	#note: hijos que tiene en item actualmente
	lista_actual= []
	for relacion in itemActual.relacionHijo:
		item_aux= relacion.hijo
		if item_aux.getEstado() != 'Eliminado' and (item_aux in fase.items):
			lista_actual.append(item_aux)
	#note: comprueba si algun item candidato ya posee un padre
	for item in fase.items:
		if item != itemActual and item.getEstado() != 'Eliminado' :
			for relacion in item.relacionHijo:
				if relacion.hijo in lista_vista:
					# otro item ya es padre, de uno de los items que se quiere relacionar
					print "\n\n\n\n\n\n\n\n\n"
					print "ALgun item de la lista ya tiene un padre asignado"
					print "\n\n\n\n\n\n\n\n\n"
					output= json.dumps({'success': False, 'mensaje': 'Algun item de la lista ya tiene un padre asignado '})
					return Response(output)
	#note: comprueba si existe un ciclo
	itemActual2= itemActual
	while itemActual2.getPadre(fase) != None:
		if itemActual2.getPadre(fase) in lista_vista:
			print "\n\n\n\n\n\n\n\n\n"
			print "Existe un ciclo, es imposible la relacion"
			print "\n\n\n\n\n\n\n\n\n"
			output= json.dumps({'success': False, 'mensaje':'Existe un ciclo, es imposible la relacion'})
			return Response(output)
		else:
			itemActual2= itemActual2.getPadre(fase)
	#note: si el item ya esta relacionado se rechaza, si no se crea una relacion y anhade
	###
	nuevaVersion= Item(itemActual.getNombre(), itemActual.getComplejidad(), itemActual.getDescripcion())
	nuevaVersion.tipoItem= itemActual.tipoItem
	nuevaVersion.copiarAtributos(itemActual.getAtributos(), item.getRelacionArchivos())
	nuevaVersion.setVersion(itemActual.getVersion() + 1)
	nuevaVersion.versionAnterior.append(itemActual)
	#note: guarda la nueva version
	session.add(nuevaVersion)
	nuevaVersion= session.query(Item).order_by(Item.id)[-1]
	nuevaVersion= nuevaVersion.copiarRelaciones(itemActual, session)
	session.add(nuevaVersion)
	#note: actualiza la fase
	fase.actualizarFase(session, itemActual, nuevaVersion)
	historial= Historial("Se ha modificado relaciones de hijos")
	historial.generarHistorial(nuevaVersion, session, request)
	###
	for posible in lista_vista:
		if not (posible in lista_actual) and posible != None:
			aso= RelacionHijo()
			aso.hijo= posible
			aso.left_id= nuevaVersion.id
			nuevaVersion.relacionHijo.append(aso)
			session.add(nuevaVersion)
	#note: si el item ya no se encuentra relacionado se elimina la relacion
	for posible in lista_actual:
		if not(posible in lista_vista):
			for relacion in nuevaVersion.relacionHijo:
				if relacion.hijo == posible:
					session.delete(relacion)
	"""
	output= json.dumps({'success': True, 'mensaje':'Solo se pueden observar las relaciones, no cambiar por el tema de VERSION!'})
	return Response(output)


def relacionar_sucesor(request):
	"""
	session = DBSession()
	id_item= int(request.params['id_item'])
	lista_Item= request.params['lista_Item']
	lista_Item= lista_Item[1:-1].split(',')
	#note: item seleccioando para atribuuirle relaciones
	itemActual= session.query(Item).filter_by(id= id_item).first() # item actual
	fase= session.query(Fase).filter_by(id= itemActual.fase_id).first() # fase en que se encuentra el item a relacionar
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first() # proyecto en que se encuentra el item a relacionar
	ubicacion= proyecto.fases.index(fase)
	#note: si la ubicacion del item es la ultima fase del proyecto, entonces no puede existir relacion con sucesores
	if ubicacion == (len(proyecto.fases)-1):
		output= json.dumps({'success': False})
		return Response(output)
	fasePosterior= proyecto.fases[ubicacion+1]
	#note: ids de los items, proporcionados por el extjs
	id_item_vista= []
	if lista_Item[0] != '':
		for numero in lista_Item:
			id_item_vista.append(int(numero))
	#note: items del lado derecho del DRAG
	lista_vista= []
	for id_aux in id_item_vista:
		item= session.query(Item).filter_by(id= id_aux).first()
		lista_vista.append(item)
	#note: hijos que tiene en item actualmente
	lista_actual= []
	for relacion in itemActual.relacionSucesor:
		item_aux= relacion.item
		if item_aux.getEstado() != 'Eliminado' and (item_aux in fasePosterior.items):
			lista_actual.append(item_aux)
	#note: si el item ya esta relacionado se rechaza, si no se crea una relacion y anhade
	###
	nuevaVersion= Item(itemActual.getNombre(), itemActual.getComplejidad(), itemActual.getDescripcion())
	nuevaVersion.tipoItem= itemActual.tipoItem
	nuevaVersion.copiarAtributos(itemActual.getAtributos(), item.getRelacionArchivos())
	nuevaVersion.setVersion(itemActual.getVersion() + 1)
	nuevaVersion.versionAnterior.append(itemActual)
	#note: guarda la nueva version
	session.add(nuevaVersion)
	nuevaVersion= session.query(Item).order_by(Item.id)[-1]
	nuevaVersion= nuevaVersion.copiarRelaciones(itemActual, session)
	session.add(nuevaVersion)
	#note: actualiza la fase
	fase.actualizarFase(session, itemActual, nuevaVersion)
	historial= Historial("Se ha modificado relaciones sucesor")
	historial.generarHistorial(nuevaVersion, session, request)
	###
	for posible in lista_vista:
		if not (posible in lista_actual) and posible != None:
			aso= RelacionSucesor()
			aso.item= posible
			aso.left_id= nuevaVersion.id
			nuevaVersion.relacionSucesor.append(aso)
			session.add(nuevaVersion)
	#note: si el item ya no se encuentra relacionado se elimina la relacion
	for posible in lista_actual:
		if not(posible in lista_vista):
			for relacion in nuevaVersion.relacionSucesor:
				if relacion.item == posible:
					session.delete(relacion)
	"""
	output= json.dumps({'success': True, 'mensaje': 'Solo se pueden observar las relaciones, no cambiar por el tema de VERSION!'})
	return Response(output)

#ordenado +-
def revivir_items(request):
	session = DBSession()
	id_item= int(request.params['id'])
	item= session.query(Item).filter_by(id= id_item).first()
	"""
	note: filtro que controla que al revivir el item, algun item de la fase tenga dos padres (uno de ellos el item a revivir)
	"""
	fase= session.query(Fase).filter_by(id= item.fase_id).first()
	hijos_del_muerto= []
	for relacion in item.relacionHijo:
		if (relacion.hijo in fase.items) and (relacion.hijo.getEstado() != 'Eliminado'):
			hijos_del_muerto.append(relacion.hijo)
	for item_aux in fase.items:
		if (item != item_aux) and (item_aux.getEstado() != 'Eliminado'):
			for relacion in item_aux.relacionHijo:
				if relacion.hijo.getEstado() != 'Eliminado' and (relacion.hijo in hijos_del_muerto):
					print "\n\n\n\n\n\n\n\n"
					print "si se revive existirian dos padres, esto no puede ser"
					print "\n\n\n\n\n\n\n\n"
					output= json.dumps({'success': False, 'mensaje':'Error: si se revive existirian dos padres para un item, esto no puede ser'})
					return Response(output)
	###
	fase= session.query(Fase).filter_by(id= item.fase_id).first()
	nuevaVersion= Item(item.getNombre(), item.getComplejidad(), item.getDescripcion())
	nuevaVersion.tipoItem= item.tipoItem
	nuevaVersion.copiarAtributos(item.getAtributos(), item.getRelacionArchivos())
	nuevaVersion.setVersion(item.getVersion() + 1)
	nuevaVersion.versionAnterior.append(item)
	"""
	note: guarda la nueva version
	"""
	session.add(nuevaVersion)
	nuevaVersion= session.query(Item).order_by(Item.id)[-1]
	nuevaVersion= nuevaVersion.copiarRelaciones(item, session)
	session.add(nuevaVersion)
	"""
	note: actualiza la fase
	"""
	fase.items.sort(comparaId)
	fase.actualizarFase(session, item, nuevaVersion)
	fase.actualizarEstado()
	session.add(fase)
	"""
	note: seccion historial
	"""
	item= session.query(Item).order_by(Item.id)[-1]
	historial= Historial("Se ha revivido el item, con nueva version")
	historial.generarHistorial(item, session, request)
	###
	output= json.dumps({'success': True, 'mensaje':'Se ha revivido el item, con nueva version'})
	return Response(output)

#4
def aprobar_items(request):
	session = DBSession()
	id_item= int(request.params['id'])
	item= session.query(Item).filter_by(id= id_item).first()
	fase= session.query(Fase).filter_by(id= item.fase_id).first()
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	proyecto.fases.sort(comparaFase) # ordena la fase por su posicion
	ubicacion= proyecto.fases.index(fase)
	if ubicacion != 0: 
		# funcion que comprueba que todos sus antecesores, en la fase anterior estan bloqueados
		antecesores= item.getAntecesoresParaLb(session, fase)
		for item_aux in antecesores:
			if item_aux.getEstado() != 'Bloqueado':
				print "\n\n\n\n\n\n"
				print "Error: existe un antecesor que no esta en una Linea Base Cerrada"
				print "\n\n\n\n\n\n"
				output= json.dumps({'success': False, 'mensaje': 'Error: existe un antecesor que no esta en una Linea Base Cerrada'})# hay que poner mensajes personalizados
				return Response(output)
		if item.tienePadre(fase):
			if (item.getPadre(fase)).getEstado() != 'Aprobado':
				print "\n\n\n\n\n\n"
				print "Error: el padre del item debe estar en estado Aprobado"
				print "\n\n\n\n\n\n"
				output= json.dumps({'success': False, 'mensaje': 'Error: el padre del item debe estar en estado Aprobado'})# hay que poner mensajes personalizados
				return Response(output)
		if antecesores == [] and not item.tienePadre(fase):
			print "\n\n\n\n\n\n"
			print "Error: el item no esta en la primera fase, y no posee ningun tipo de relacion valida, no puede ser Aprobado"
			print "\n\n\n\n\n\n"
			output= json.dumps({'success': False, 'mensaje': 'Error: el item no esta en la primera fase, y no posee ningun tipo de relacion, no puede ser Aprobado'})# hay que poner mensajes personalizados
			return Response(output)
	if item.getEstado() == 'Aprobado':
		output= json.dumps({'success': False, 'mensaje': 'Error: el item ya se encuentra Aprobado'})# hay que poner mensajes personalizados
		return Response(output)
	if item.getEstado() == 'Bloqueado':
		output= json.dumps({'success': False, 'mensaje': 'Error: el item se encuentra Bloqueado'})# hay que poner mensajes personalizados
		return Response(output)
	item.setEstado('Aprobado')
	session.add(item)
	fase= session.query(Fase).filter_by(id= item.fase_id).first()
	#fase.items.sort(compara)# ordena los items
	fase.actualizarEstado()
	session.add(fase)
	output= json.dumps({'success': True, 'mensaje': 'El item ha sido aprobado con exito'})
	return Response(output)


def desaprobar_items(request):
	session = DBSession()
	id_item= int(request.params['id'])
	item= session.query(Item).filter_by(id= id_item).first()
	if item.getEstado() == 'Bloqueado':
		output= json.dumps({'success': False})# mensaje el item esta bloqueado
		return Response(output)
	if item.getEstado() != 'Desaprobado':
		item.setEstado('Desaprobado')
		session.add(item)
	output= json.dumps({'success': True})
	return Response(output)


def cambiarContrasenha(request):
	session = DBSession()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	passActual= request.params['passwordActual']
	passNuevo= request.params['password1']
	if Usuario.check_password(en_linea, passActual):
		usuario.password= passNuevo
		session.add(usuario)
		output= json.dumps({'success': True, 'mensaje': 'El password se ha modificado correctamente'})
	else:
		output= json.dumps({'success': False, 'mensaje': 'El password actual no coincide con el almacenado en el sistema'})
	return Response(output)


def modificar_usuario_en_linea(request):
	session= DBSession()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	output= json.dumps({'success': True, 'mensaje': 'La modificacion se realizo con exito'})
	if usuario != None:
		modificadoNombreUsuario= False
		modificadoNombre= False
		modificadoApellido= False
		modificadoTelefono= False
		modificadoNroDocumento= False
		modificadoMail= False
		if usuario.getNombre() != request.params['nombre']:
			usuario.setNombre(request.params['nombre'])
			modificadoNombre= True
		if usuario.getApellido() != request.params['apellido']:
			usuario.setApellido( request.params['apellido'])
			modificadoApellido= True
		if usuario.getTelefono() != request.params['telefono']:
			usuario.setTelefono(request.params['telefono'])
			modificadoTelefono= True
		if usuario.getNroDocumento() != request.params['nroDocumento']:
			usuario.setNroDocumento(request.params['nroDocumento'])
			modificadoNroDocumento= True
		if usuario.getMail() != request.params['email']:
			usuario.setMail( request.params['email'])
			modificadoMail= True
		if modificadoNombreUsuario or modificadoNombre or modificadoApellido or modificadoTelefono or modificadoMail or modificadoNroDocumento:
			session.add(usuario)
	return Response(output)


def adjuntar_imagen_usuario(request):
	session= DBSession()
	print "\n\n\n\n\n\n"
	form = request.params['imagen']
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	usuario.setNombreImagen(form.filename)
	usuario.setTipoImagen(form.type) 
	usuario.setImagen(form.value)
	session.add(usuario)
	print "\n\n\n\n\n\n"
	output= json.dumps({'success': True})
	return Response(output)


def imagen_usuario(request):
	session= DBSession()
	en_linea= authenticated_userid(request)
	usuario= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	imagen= usuario.getImagen()
	return Response(imagen)


def adjuntar_archivo_item(request):
	session= DBSession()
	identificador = request.params['id_item']
	form = request.params['archivo']# aca hay que definir como se llama 
	item= session.query(Item).filter_by(id= identificador).first()
	if item.getEstado() == 'Bloqueado':
		print "\n\n\n\n\n\n imposible, esta en una linea base cerrada \n\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje': 'Error: imposible, esta en una linea base cerrada'})
		return Response(output)
	archivo= Archivo()
	archivo.setNombreArchivo(form.filename)
	archivo.setTipoArchivo(form.type) 
	archivo.setArchivo(form.value)
	asociacion= AsociacionItemArchivo()
	asociacion.archivo= archivo
	item.relacionArchivo.append(asociacion)
	session.add(item)
	output= json.dumps({'success': True, 'mensaje':'Se ha subido el archivo con exito'})
	return Response(output)


def archivo_item2(request):
	session= DBSession()
	identificador= request.matchdict['id_archivo'] 
	archivo= session.query(Archivo).filter_by(id= identificador).first()
	contenido= archivo.getArchivo()
	response= Response(content_type='application/force-download')
	response.app_iter= contenido
	return response


def archivo_item(request):
	id = request.params['id']
	nombreArchivo = request.params['nombre']
	return HTTPFound(location = request.route_url('archivo_item2', id_archivo=id,nombre=nombreArchivo))


def eliminar_archivo_item(request):
	session= DBSession()
	idArchivo= int(request.params['id'])
	archivo= session.query(Archivo).filter_by(id= idArchivo).first()
	asociaciones= session.query(AsociacionItemArchivo).filter_by(right_id= archivo.id).all()
	for aso in asociaciones:
		session.delete(aso)
	session.delete(archivo)
	output= json.dumps({'success': True})
	return Response(output)


def generar_linea_base(request):
	session= DBSession()
	idFase= int(request.params['idFase'])
	""" note: lista_Item contiene todos los ids de los items mandados, en el DRAG derecho para asignar """
	lista_Item= request.params['lista_Item']
	lista_Item= lista_Item[1:-1].split(',')
	id_items= []
	""" note: precondicion del sistema , no puede estar vacia la linea base"""
	if lista_Item[0] == '':
		print "\n\n\n\n Error: la lista de items para la linea base esta vacia \n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje':'Error: la lista de items para la linea base esta vacia'})
		return Response(output)
	
	for numero in lista_Item:
		id_items.append(int(numero))
	# note: items del lado derecho del DRAG 
	lista_vista= []
	for id_aux in id_items:
		item= session.query(Item).filter_by(id= id_aux).first()
		lista_vista.append(item)
	# note: termina la parte de captar datos, comienza la logica 
	fase= session.query(Fase).filter_by(id= idFase).first()
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	nuevaLinea= LineaBase()
	for aux_item in lista_vista:
		aux_item.setEstado('Bloqueado')
		nuevaLinea.items.append(aux_item)
	fase.lineasBase.append(nuevaLinea) # anhade la nueva linea base a la fase
	fase.refrescarLineasBase(session) # elimina  los items eliminados y los pasados de versiones
	fase.actualizarEstado() # actualiza su estado de acuerdo al estado de sus items
	session.add(fase)
	fase.lineasBase.sort(comparaId) # ordena como una cola
	fase.reEnumerarLineasBase() # reenumera las linas base
	fase.autoNombrarLineasBase() # nombra las lineas base
	session.add(fase)
	fase.eliminarLineasBaseVacias(session) # elimina las lineas bases vacias
	output= json.dumps({'success': True, 'mensaje':'La Linea Base ha sido generada con exito'})
	return Response(output)


def romper_linea_base(request):
	session= DBSession()
	id_linea= int(request.params['id'])
	lineaBase= session.query(LineaBase).filter_by(id= id_linea).first()
	fase= session.query(Fase).filter_by(id= lineaBase.fase_id).first()
	afectados= lineaBase.getItems()
	""" note: precondicion del sistema , no puede estar vacia la linea base"""
	if lineaBase.getEstado() != 'Cerrada':
		output= json.dumps({'success': False, 'mensaje': 'Error: la Linea Base debe estar Cerrada para romperse' })# hay que poner mensajes personalizados
		return Response(output)
	for item in afectados:
		item.setEstado('Revision')
		antecesores= item.getAntecesoresParaLb(session, fase)
		sucesores= item.getSucesoresParaLb(session, fase)
		for itemAntecesor in antecesores:
			itemAntecesor.setEstado('Revision')
			session.add(itemAntecesor)
			if itemAntecesor.tieneLineaBase():
				lb= itemAntecesor.getLineaBase(session)
				lb.comprometer(session)
				session.add(lb)
			faseAnterior= session.query(Fase).filter_by(id= itemAntecesor.fase_id).first()
			faseAnterior.actualizarEstado()
			session.add(faseAnterior)
		for itemSucesor in sucesores:
			itemSucesor.setEstado('Revision')
			session.add(itemSucesor)
			if itemSucesor.tieneLineaBase():
				lb= itemSucesor.getLineaBase(session)
				lb.comprometer(session)
				session.add(lb)
			fasePosterior= session.query(Fase).filter_by(id= itemSucesor.fase_id).first()
			fasePosterior.actualizarEstado()
			session.add(fasePosterior)
		if item.tienePadre(fase):
			aux= item.getPadre(fase)
			aux.setEstado('Revision')
			session.add(aux)
			if aux.tieneLineaBase():
				lb= aux.getLineaBase(session)
				lb.comprometer(session)
				session.add(lb)
		for relacion in item.relacionHijo:
			hijo= relacion.hijo
			hijo.setEstado('Revision')
			session.add(hijo)
			if hijo.tieneLineaBase():
				lb= hijo.getLineaBase(session)
				lb.comprometer(session)
				session.add(lb)
	lineaBase.setEstado('Abierta')
	fase.actualizarEstado()
	session.add(fase)
	output= json.dumps({'success': True, 'mensaje': 'Se ha roto con exito la Linea Base'})
	return Response(output)


def cerrar_linea_base(request):
	session= DBSession()
	id_linea= int(request.params['id'])
	lineaBase= session.query(LineaBase).filter_by(id= id_linea).first()
	""" note: precondicion, deben estar en un estado diferente al de Cerrada"""
	if lineaBase.getEstado() == 'Cerrada':
		output= json.dumps({'success': False, 'mensaje': 'Error: la Linea Base ya se encuentra en estado Cerrada' })# hay que poner mensajes personalizados
		return Response(output)
	fase= session.query(Fase).filter_by(id= lineaBase.fase_id).first()
	afectados= lineaBase.getItems()
	""" note: precondicion, todos los items deben estar en estado Aprobado"""
	for item in afectados:
		if item.getEstado() != 'Aprobado':
			output= json.dumps({'success': False, 'mensaje': 'Error: existe un item que no esta en estado Aprobado, no se puede cerrar' })# hay que poner mensajes personalizados
			return Response(output)
	#for aux in afectados:
	#	lineaBase.items.remove(aux)
	nuevaLinea= LineaBase()
	for item in afectados:
		item.setEstado('Bloqueado')
		lineaBase.items.remove(item)
		print "\n\n"
		print lineaBase.items
		print "\n\n"
		nuevaLinea.items.append(item)
	
	fase.lineasBase.append(nuevaLinea) # anhade la nueva linea base a la fase
	fase.refrescarLineasBase(session) # elimina  los items eliminados y los pasados de versiones
	fase.actualizarEstado() # actualiza su estado de acuerdo al estado de sus items
	session.add(fase)
	fase.lineasBase.sort(comparaId) # ordena como una cola
	fase.reEnumerarLineasBase() # reenumera las linas base
	fase.autoNombrarLineasBase() # nombra las lineas base
	session.add(fase)
	#fase= session.query(Fase).filter_by(id= fase.id).first()
	fase.eliminarLineasBaseVacias(session) # elimina las lineas bases vacias
	output= json.dumps({'success': True, 'mensaje': 'Se ha cerrado con exito la Linea Base'})
	return Response(output)


def calcular_impacto_delante(request):
	session= DBSession()
	idItem= int(request.matchdict['idItem'])
	item= session.query(Item).filter_by(id= idItem).first()
	fase= session.query(Fase).filter_by(id= item.fase_id).first()
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	for fase_aux in proyecto.fases:
		for item_aux in fase_aux.items:
			item_aux.setDesMarcar()
			session.add(item_aux)
	"""
	note: items que son sucesores, inclyendo el item
	"""
	lista= item.getSucesores(session ,fase, item)
	"""
	note: elimina duplicados
	"""
	lista= eliminar_duplicados(lista)
	cont= 0
	for aux in lista:
		cont= cont +  aux.getComplejidad()
		aux.setMarcar()
		session.add(aux)
	return HTTPFound(location = request.route_url('grafo_calcular_impacto_delante', idProyecto= fase.proyecto_id ,impacto= cont))


def calcular_impacto_atras(request):
	session= DBSession()
	idItem= int(request.matchdict['idItem'])
	item= session.query(Item).filter_by(id= idItem).first()
	fase= session.query(Fase).filter_by(id= item.fase_id).first()
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	for fase_aux in proyecto.fases:
		for item_aux in fase_aux.items:
			item_aux.setDesMarcar()
			session.add(item_aux)
	"""
	note: items que son antecesores, incluyendo el item
	"""
	lista= item.getAntecesores(session ,fase, item)
	"""
	note: elimina duplicados
	"""
	lista= eliminar_duplicados(lista)
	cont= 0
	for aux in lista:
		cont= cont +  aux.getComplejidad()
		aux.setMarcar()
		session.add(aux)
	return HTTPFound(location = request.route_url('grafo_calcular_impacto_delante', idProyecto= fase.proyecto_id ,impacto= cont))


def calcular_impacto_total(request):
	session= DBSession()
	idItem= int(request.matchdict['idItem'])
	item= session.query(Item).filter_by(id= idItem).first()
	fase= session.query(Fase).filter_by(id= item.fase_id).first()
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	for fase_aux in proyecto.fases:
		for item_aux in fase_aux.items:
			item_aux.setDesMarcar()
			session.add(item_aux)
	"""
	note: items que son antecesores, incluyendo el item
	"""
	lista= item.getAntecesores(session ,fase, item)
	"""
	note: items que son sucesores, incluyendo el item
	"""
	listaAdd= item.getSucesores(session ,fase, item)
	"""
	note: concatena las listas
	"""
	lista.extend(listaAdd)
	"""
	note: elimina duplicados
	"""
	lista= eliminar_duplicados(lista)
	cont= 0
	for aux in lista:
		cont= cont +  aux.getComplejidad()
		aux.setMarcar()
		session.add(aux)
	return HTTPFound(location = request.route_url('grafo_calcular_impacto_delante', idProyecto= fase.proyecto_id ,impacto= cont))


def asignar_lider_fase(request):
	"""Funcion que se encarga de asignar el rol de lider a una fase
	:return: retorna al extj un mensaje de si la operacion fue un exito o no"""
	session = DBSession()
	id_fase= int(request.params['id_fase'])
	print "\n\n\n\n\n"
	print request.params
	print "\n\n\n\n\n"
	en_linea= authenticated_userid(request)
	usuarioEnLinea= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	lista_usuarios= request.params['lista_usuarios']
	lista_usuarios= lista_usuarios[1:-1].split(',')
	username= lista_usuarios[0]
	usuario_vista= session.query(Usuario).filter_by( nombreUsuario= username[1:-1] ).first()
	fase= session.query(Fase).filter_by( id= id_fase ).first()
	proyecto= session.query(Fase).filter_by( id= fase.proyecto_id ).first()
	"""
	if not usuarioEnLinea.esLider(proyecto):
		output= json.dumps({'success': False, 'mensaje': 'Usted no es lider del proyecto'})
		return Response(output)
	"""
	usuario_sistema= session.query(Usuario).filter_by( id= fase.lider_id ).first()
	if usuario_vista == None and usuario_sistema == None:
		output= json.dumps({'success': False, 'mensaje': 'No existe lider asignado a la fase'})
	elif usuario_sistema != None and usuario_vista == None:
		usuario_sistema.liderFase.remove(fase)
		fase.lider_id= None
		session.add(usuario_sistema)
		session.add(fase)
		output= json.dumps({'success': True, 'mensaje':'Lider desasignado correctamente' })
	elif usuario_sistema == None and usuario_vista != None:
		usuario_vista.liderFase.append(fase)
		session.add(usuario_vista)
		output= json.dumps({'success': True, 'mensaje':'Lider asignado correctamente'})
	else :
		if usuario_vista != usuario_sistema:
			usuario_sistema.liderFase.remove(fase)
			usuario_vista.liderFase.append(fase)
			session.add(usuario_sistema)
			session.add(usuario_vista)
			output= json.dumps({'success': True, 'mensaje':'Lider intercambiado correctamente'})
		else:
			output= json.dumps({'success': True, 'mensaje':'No se realizo ningun cambio'})
	return Response(output)

##hay que corregir
def asignar_fase_desarrollador(request):
	session = DBSession()
	id_usuario= int(request.params['id_usuario'])
	id_proyecto= int(request.params['id_proyecto'])
	lista_fases= request.params['lista_fases']
	lista_fases= lista_fases[1:-1].split(',')
	id_fases= []
	###
	id_proyecto= int(request.params['id_proyecto'])
	proyecto=  session.query(Proyecto).filter_by(id= id_proyecto).first()
	en_linea= authenticated_userid(request)
	usuarioEnLinea= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if not usuarioEnLinea.esLider(proyecto):
		print "\n\n\n\n\n"
		print "Usted no es lider"
		print "\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje':'Usted no es lider del Proyecto'})
		return Response(output)
	##
	if lista_fases[0] != '':
		for numero in lista_fases:
			id_fases.append(int(numero))
	usuario= session.query(Usuario).filter_by(id= id_usuario).first()
	lista_vista= []
	lista_actuales= []
	#note: fases que estan al lado derecho del DRAG
	for id_fase in id_fases:
		fase= session.query(Fase).filter_by(id= id_fase).first()
		lista_vista.append(fase)
	#note: proyectos que tiene actualmente el rol
	tiene= False
	for relacion in usuario.asociacionRol:
		rol= relacion.rol
		if rol.getTipo() == 'Comodin':
			tiene= True
			rolNow= rol
			for aso in rol.asociacionFase:
				lista_actuales.append(aso.fase)
	if not tiene:
		nuevo= Rol(usuario.getNombreUsuario() + '#', 'Comodin')
		nuevo.setTipo('Comodin')
		asociacion= AsociacionUsuarioRol()
		asociacion.rol= nuevo
		usuario.asociacionRol.append(asociacion)
		session.add(usuario)
		rolNow= session.query(Rol).order_by(Rol.id)[-1]
	#note: si la fase de la vista no esta, se crea la relacion y se anhade
	for posible in lista_vista: 
		if not (posible in lista_actuales) and posible != None:
			aso= AsociacionRolFase()
			aso.fase= posible
			aso.left_id= rol.id
			rolNow.asociacionFase.append(aso)
	session.add(rol)
	#note: si la fase no esta en la vista, se elimina su relacion con el rol
	for posible in lista_actuales:
		if posible in proyecto.fases:
			if not(posible in lista_vista):
				for aso in rolNow.asociacionFase:
					if aso.fase == posible:
						session.delete(aso)
	output= json.dumps({'success': True, 'mensaje':'Gestion realizada'})
	return Response(output)


def asignar_tipo_desarrollador(request):
	session = DBSession()
	id_usuario= int(request.params['id_usuario'])
	id_proyecto= int(request.params['id_proyecto'])
	lista_tiposItem= request.params['lista_tiposItem']
	lista_tiposItem= lista_tiposItem[1:-1].split(',')
	id_tipos= []
	###
	id_proyecto= int(request.params['id_proyecto'])
	proyecto=  session.query(Proyecto).filter_by(id= id_proyecto).first()
	en_linea= authenticated_userid(request)
	usuarioEnLinea= session.query(Usuario).filter_by(nombreUsuario= en_linea).first()
	if not usuarioEnLinea.esLider(proyecto):
		print "\n\n\n\n\n"
		print "Usted no es lider"
		print "\n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje':'Usted no es lider del Proyecto'})
		return Response(output)
	##
	if lista_tiposItem[0] != '':
		for numero in lista_tiposItem:
			id_tipos.append(int(numero))
	usuario= session.query(Usuario).filter_by(id= id_usuario).first()
	lista_vista= []
	lista_actuales= []
	#note: fases que estan al lado derecho del DRAG
	for id_tipo in id_tipos: 
		tipo= session.query(TipoItem).filter_by(id= id_tipo).first()
		lista_vista.append(tipo)
	#note: proyectos que tiene actualmente el rol
	tiene= False
	for relacion in usuario.asociacionRol:
		rol= relacion.rol
		if rol.getTipo() == 'Comodin':
			tiene= True
			rolNow= rol
			for aso in rol.asociacionTipoItem:
				lista_actuales.append(aso.tipoItem)
	if not tiene:
		nuevo= Rol(usuario.getNombreUsuario() + '#', 'Comodin')
		nuevo.setTipo('Comodin')
		asociacion= AsociacionUsuarioRol()
		asociacion.rol= nuevo
		usuario.asociacionRol.append(asociacion)
		session.add(usuario)
		rolNow= session.query(Rol).order_by(Rol.id)[-1]
	#note: si la fase de la vista no esta, se crea la relacion y se anhade
	for posible in lista_vista: 
		if not (posible in lista_actuales) and posible != None:
			aso= AsociacionRolTipoItem()
			aso.tipoItem= posible
			aso.left_id= rol.id
			rolNow.asociacionTipoItem.append(aso)
	session.add(rol)
	#note: si la fase no esta en la vista, se elimina su relacion con el rol
	for posible in lista_actuales:
		if posible in proyecto.tipoItems:
			if not(posible in lista_vista):
				for aso in rolNow.asociacionTipoItem:
					if aso.tipoItem == posible:
						session.delete(aso)
	output= json.dumps({'success': True, 'mensaje':'Gestion realizada'})
	return Response(output)


def reordenar_fases(request):
	session= DBSession()
	id_proyecto= int(request.params['id_proyecto'])
	lista_fases= request.params['lista_fases']
	lista_fases= lista_fases[1:-1].split(',')
	print "\n\n\n\n\n"
	print request.params
	print "\n\n\n\n\n"
	proyecto= session.query(Proyecto).filter_by(id= id_proyecto).first()
	if proyecto.getEstado() != 'No iniciado':
		print "\n\n\n\n Error: El proyecto ya se ha iniciado, no se pueden permutar las fases \n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje': 'Error: El proyecto ya se ha iniciado, no se pueden permutar las fases'})
		return Response(output)
	if lista_fases[0] == '':
		print "\n\n\n\n Error: La lista de fases esta vacia \n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje': 'Error: La lista de fases esta vacia'})
		return Response(output)
	if len(proyecto.fases) != len(lista_fases):
		print "\n\n\n\n Error: La lista de fases no contiene todas las fases del proyecto \n\n\n\n\n"
		output= json.dumps({'success': False, 'mensaje': 'Error: La lista de fases no contiene todas las fases del proyecto'})
		return Response(output)
	# note: items del lado derecho del DRAG
	id_fases= []
	for id_fase in lista_fases:
		id_fases.append(int(id_fase))
	cont= 0
	for id_aux in id_fases:
		fase= session.query(Fase).filter_by(id= id_aux).first()
		cont= cont + 1
		fase.setPosicionFase(cont)
		session.add(fase)
	output= json.dumps({'success': True, 'mensaje': 'Las fases se reordenaron bien'})
	return Response(output)


def grafo_LB(request):
	session= DBSession()
	linea= int(request.matchdict['idLineaBase'])
	lineaBase= session.query(LineaBase).filter_by(id= linea).first()
	fase= session.query(Fase).filter_by(id= lineaBase.fase_id).first()
	proyecto= session.query(Proyecto).filter_by(id= fase.proyecto_id).first()
	for fase_aux in proyecto.fases:
		for item_aux in fase_aux.items:
			item_aux.setDesMarcar()
			session.add(item_aux)
	"""
	note: items que son antecesores, incluyendo el item
	"""
	lista= lineaBase.getItems()
	"""
	note: elimina duplicados
	"""
	lista= eliminar_duplicados(lista)
	cont= lineaBase.getComplejidad()
	for aux in lista:
		aux.setMarcar()
		session.add(aux)
	return HTTPFound(location = request.route_url('grafo_linea_base', idProyecto= fase.proyecto_id ,impacto= cont))
